Update of /cvsroot/linux-vax/kernel-2.4/arch/mips/dec In directory usw-pr-cvs1:/tmp/cvs-serv16972/mips/dec Modified Files: Makefile int-handler.S irq.c reset.c rtc-dec.c setup.c time.c wbflush.c Removed Files: serial.c Log Message: synch 2.4.15 Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/Makefile,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- Makefile 14 Jan 2001 19:28:53 -0000 1.1.1.1 +++ Makefile 10 Apr 2002 14:38:05 -0000 1.2 @@ -7,30 +7,19 @@ # .S.s: - $(CPP) $(CFLAGS) $< -o $*.s + $(CPP) $(AFLAGS) $< -o $@ .S.o: - $(CC) $(CFLAGS) -c $< -o $*.o + $(CC) $(AFLAGS) -c $< -o $@ -all: dec.o O_TARGET := dec.o -O_OBJS := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o -ifdef CONFIG_PROM_CONSOLE -O_OBJS += promcon.o -endif +all: dec.o -ifdef CONFIG_SERIAL -O_OBJS += serial.o -endif +export-objs := wbflush.o +obj-y := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o -ifeq ($(CONFIG_MODULES),y) - OX_OBJS = wbflush.o -else - O_OBJS += wbflush.o -endif +obj-$(CONFIG_PROM_CONSOLE) += promcon.o int-handler.o: int-handler.S - -clean: include $(TOPDIR)/Rules.make Index: int-handler.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/int-handler.S,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- int-handler.S 14 Jan 2001 19:28:54 -0000 1.1.1.1 +++ int-handler.S 10 Apr 2002 14:38:05 -0000 1.2 @@ -2,6 +2,7 @@ * arch/mips/dec/int-handler.S * * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen + * Copyright (C) 2000 Maciej W. Rozycki * * Written by Ralf Baechle and Andreas Busse, modified for DECStation * support by Paul Antoine and Harald Koerfgen. @@ -16,6 +17,11 @@ #include <asm/stackframe.h> #include <asm/addrspace.h> +#include <asm/dec/kn01.h> +#include <asm/dec/kn02.h> +#include <asm/dec/kn02xa.h> +#include <asm/dec/kn03.h> +#include <asm/dec/ioasic_addrs.h> #include <asm/dec/interrupts.h> @@ -24,8 +30,6 @@ /* * decstation_handle_int: Interrupt handler for DECStations * - * FIXME: Detection of spurious interrupts not yet implemented! - * * We follow the model in the Indy interrupt code by David Miller, where he * says: a lot of complication here is taken away because: * @@ -139,12 +143,12 @@ la t1,cpu_mask_tbl and t0,t2 # isolate allowed ones - /* insert detection of spurious interrupts here */ + beqz t0,spurious /* * Find irq with highest priority */ -1: lw t2,(t1) +1: lw t2,(t1) move t3,t0 and t3,t2 beq t3,zero,1b @@ -156,18 +160,18 @@ lw a0,%lo(cpu_irq_nr-cpu_mask_tbl-PTRSIZE)(t1) lw t0,%lo(cpu_ivec_tbl-cpu_mask_tbl-PTRSIZE)(t1) bgez a0, handle_it # irq_nr >= 0? - # irq_nr < 0: a0 contains an address - nop + # irq_nr < 0: t0 contains an address + nop jr t0 nop # delay slot /* * Handle "IRQ Controller" Interrupts * Masked Interrupts are still visible and have to be masked "by hand". - * %hi(KN02_CSR_ADDR) does not work so all addresses are hardcoded :-(. */ EXPORT(kn02_io_int) -kn02_io_int: lui t0,0xbff0 # get interrupt status and mask +kn02_io_int: # 3max + lui t0,KN02_CSR_ADDR>>16 # get interrupt status and mask lw t0,(t0) la t1,asic_mask_tbl move t3,t0 @@ -176,27 +180,32 @@ and t0,t3 # mask out allowed ones EXPORT(kn03_io_int) -kn03_io_int: lui t2,0xbf84 # upper part of IOASIC Address - lw t0,0x0110(t2) # get status: IOASIC isr - lw t3,0x0120(t2) # get mask: IOASIC isrm +kn03_io_int: # 3max+ + lui t2,KN03_IOASIC_BASE>>16 # upper part of IOASIC Address + lw t0,SIR(t2) # get status: IOASIC isr + lw t3,SIMR(t2) # get mask: IOASIC isrm la t1,asic_mask_tbl b find_int and t0,t3 # mask out allowed ones - EXPORT(kn02ba_io_int) -kn02ba_io_int: lui t2,0xbc04 - lw t0,0x0110(t2) # IOASIC isr, works for maxine also - lw t3,0x0120(t2) # IOASIC isrm + EXPORT(kn02xa_io_int) +kn02xa_io_int: # 3min/maxine + lui t2,KN02XA_IOASIC_BASE>>16 + # upper part of IOASIC Address + lw t0,SIR(t2) # get status: IOASIC isr + lw t3,SIMR(t2) # get mask: IOASIC isrm la t1,asic_mask_tbl and t0,t3 /* * Find irq with highest priority */ -find_int: lw t2,(t1) +find_int: beqz t0,spurious + +1: lw t2,(t1) move t3,t0 and t3,t2 - beq zero,t3,find_int + beq zero,t3,1b addu t1,PTRSIZE # delay slot /* @@ -209,7 +218,10 @@ move a1,sp j ret_from_irq nop - + +spurious: + j spurious_interrupt + nop END(decstation_handle_int) /* * Interrupt routines common to all DECStations first. @@ -218,14 +230,6 @@ dec_intr_fpu: PANIC("Unimplemented FPU interrupt handler") /* - * Halt interrupt - */ - EXPORT(intr_halt) -intr_halt: la k0,0xbc000000 - jr k0 - nop - -/* * Generic unimplemented interrupt routines - ivec_tbl is initialised to * point all interrupts here. The table is then filled in by machine-specific * initialisation in dec_setup(). @@ -358,5 +362,3 @@ .word 0 .word 0 .word 0xffffffff # EOL - - Index: irq.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/irq.c,v retrieving revision 1.1.1.2 retrieving revision 1.2 diff -u -r1.1.1.2 -r1.2 --- irq.c 25 Feb 2001 23:15:18 -0000 1.1.1.2 +++ irq.c 10 Apr 2002 14:38:05 -0000 1.2 @@ -2,9 +2,7 @@ * Code to handle DECstation IRQs plus some generic interrupt stuff. * * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle - * - * $Id$ + * Copyright (C) 1994, 1995, 1996, 1997, 2000 Ralf Baechle */ #include <linux/errno.h> #include <linux/init.h> @@ -27,9 +25,14 @@ #include <asm/dec/interrupts.h> -extern volatile unsigned int *isr; /* address of the interrupt status register */ -extern volatile unsigned int *imr; /* address of the interrupt mask register */ -extern decint_t dec_interrupt[NR_INTS]; +extern void dec_init_kn01(void); +extern void dec_init_kn230(void); +extern void dec_init_kn02(void); +extern void dec_init_kn02ba(void); +extern void dec_init_kn02ca(void); +extern void dec_init_kn03(void); + +extern asmlinkage void decstation_handle_int(void); unsigned long spurious_count = 0; @@ -42,7 +45,7 @@ dummy = *imr; dummy = *imr; } else /* This is a cpu interrupt */ - set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask); + change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask); } static inline void unmask_irq(unsigned int irq_nr) @@ -54,7 +57,7 @@ dummy = *imr; dummy = *imr; } - set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask); + change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask); } void disable_irq(unsigned int irq_nr) @@ -125,7 +128,7 @@ int do_random, cpu; cpu = smp_processor_id(); - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; mask_irq(irq); @@ -142,10 +145,10 @@ } while (action); if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); - unmask_irq(irq); __cli(); + unmask_irq(irq); } - irq_exit(cpu); + irq_exit(cpu, irq); /* unmasking and bottom half handling is done magically for us. */ } @@ -261,5 +264,34 @@ void __init init_IRQ(void) { - irq_setup(); + switch (mips_machtype) { + case MACH_DS23100: + dec_init_kn01(); + break; + case MACH_DS5100: /* DS5100 MIPSMATE */ + dec_init_kn230(); + break; + case MACH_DS5000_200: /* DS5000 3max */ + dec_init_kn02(); + break; + case MACH_DS5000_1XX: /* DS5000/100 3min */ + dec_init_kn02ba(); + break; + case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + dec_init_kn03(); + break; + case MACH_DS5000_XX: /* Personal DS5000/2x */ + dec_init_kn02ca(); + break; + case MACH_DS5800: /* DS5800 Isis */ + panic("Don't know how to set this up!"); + break; + case MACH_DS5400: /* DS5400 MIPSfair */ + panic("Don't know how to set this up!"); + break; + case MACH_DS5500: /* DS5500 MIPSfair-2 */ + panic("Don't know how to set this up!"); + break; + } + set_except_vector(0, decstation_handle_int); } Index: reset.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/reset.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- reset.c 14 Jan 2001 19:28:55 -0000 1.1.1.1 +++ reset.c 10 Apr 2002 14:38:05 -0000 1.2 @@ -23,3 +23,7 @@ back_to_prom(); } +void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs) +{ + dec_machine_halt(); +} Index: rtc-dec.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/rtc-dec.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- rtc-dec.c 14 Jan 2001 19:28:55 -0000 1.1.1.1 +++ rtc-dec.c 10 Apr 2002 14:38:05 -0000 1.2 @@ -1,13 +1,12 @@ - -/* $Id$ - +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * RTC routines for DECstation style attached Dallas chip. * - * Copyright (C) 1998 by Ralf Baechle, Harald Koerfgen + * Copyright (C) 1998, 2001 by Ralf Baechle + * Copyright (C) 1998 by Harald Koerfgen */ #include <linux/mc146818rtc.h> Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/setup.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- setup.c 14 Jan 2001 19:28:57 -0000 1.1.1.1 +++ setup.c 10 Apr 2002 14:38:05 -0000 1.2 @@ -6,11 +6,13 @@ * for more details. * * Copyright (C) 1998 Harald Koerfgen + * Copyright (C) 2000 Maciej W. Rozycki */ #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/mc146818rtc.h> #include <linux/param.h> +#include <linux/console.h> #include <asm/mipsregs.h> #include <asm/bootinfo.h> #include <linux/init.h> @@ -22,25 +24,19 @@ #include <asm/dec/kn02.h> #include <asm/dec/kn02xa.h> #include <asm/dec/kn03.h> +#include <asm/dec/ioasic.h> +#include <asm/dec/ioasic_addrs.h> #include <asm/dec/ioasic_ints.h> -extern asmlinkage void decstation_handle_int(void); -void dec_init_kn01(void); -void dec_init_kn230(void); -void dec_init_kn02(void); -void dec_init_kn02ba(void); -void dec_init_kn02ca(void); -void dec_init_kn03(void); +char *dec_rtc_base = (void *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */ -char *dec_rtc_base = (char *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */ +volatile unsigned int *ioasic_base; decint_t dec_interrupt[NR_INTS]; -/* +/* * Information regarding the IRQ Controller - * - * isr and imr are also hardcoded for different machines in int_handler.S */ volatile unsigned int *isr = 0L; /* address of the interrupt status register */ @@ -49,50 +45,17 @@ extern void dec_machine_restart(char *command); extern void dec_machine_halt(void); extern void dec_machine_power_off(void); +extern void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); extern void wbflush_setup(void); extern struct rtc_ops dec_rtc_ops; -extern void intr_halt(void); - extern int setup_dec_irq(int, struct irqaction *); void (*board_time_init) (struct irqaction * irq); -static void __init dec_irq_setup(void) -{ - switch (mips_machtype) { - case MACH_DS23100: - dec_init_kn01(); - break; - case MACH_DS5100: /* DS5100 MIPSMATE */ - dec_init_kn230(); - break; - case MACH_DS5000_200: /* DS5000 3max */ - dec_init_kn02(); - break; - case MACH_DS5000_1XX: /* DS5000/100 3min */ - dec_init_kn02ba(); - break; - case MACH_DS5000_2X0: /* DS5000/240 3max+ */ - dec_init_kn03(); - break; - case MACH_DS5000_XX: /* Personal DS5000/2x */ - dec_init_kn02ca(); - break; - case MACH_DS5800: /* DS5800 Isis */ - panic("Don't know how to set this up!"); - break; - case MACH_DS5400: /* DS5400 MIPSfair */ - panic("Don't know how to set this up!"); - break; - case MACH_DS5500: /* DS5500 MIPSfair-2 */ - panic("Don't know how to set this up!"); - break; - } - set_except_vector(0, decstation_handle_int); -} +static struct irqaction irq10 = {dec_intr_halt, 0, 0, "halt", NULL, NULL}; /* * enable the periodic interrupts @@ -112,9 +75,16 @@ setup_dec_irq(CLOCK, irq); } +/* + * Enable the halt interrupt. + */ +static void __init dec_halt_init(struct irqaction *irq) +{ + setup_dec_irq(HALT, irq); +} + void __init decstation_setup(void) { - irq_setup = dec_irq_setup; board_time_init = dec_time_init; wbflush_setup(); @@ -123,6 +93,10 @@ _machine_halt = dec_machine_halt; _machine_power_off = dec_machine_power_off; +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + rtc_ops = &dec_rtc_ops; } @@ -206,8 +180,8 @@ * Setup some memory addresses. FIXME: probably incomplete! */ dec_rtc_base = (char *) KN02_RTC_BASE; - isr = (volatile unsigned int *) KN02_CSR_ADDR; - imr = (volatile unsigned int *) KN02_CSR_ADDR; + isr = (void *) KN02_CSR_ADDR; + imr = (void *) KN02_CSR_ADDR; /* * Setup IOASIC interrupt @@ -275,16 +249,17 @@ /* * Setup some memory addresses. */ + ioasic_base = (void *) KN02XA_IOASIC_BASE; dec_rtc_base = (char *) KN02XA_RTC_BASE; - isr = (volatile unsigned int *) KN02XA_SIR_ADDR; - imr = (volatile unsigned int *) KN02XA_SIRM_ADDR; + isr = (void *) KN02XA_IOASIC_REG(SIR); + imr = (void *) KN02XA_IOASIC_REG(SIMR); /* * Setup IOASIC interrupt */ cpu_mask_tbl[0] = IE_IRQ3; cpu_irq_nr[0] = -1; - cpu_ivec_tbl[0] = kn02ba_io_int; + cpu_ivec_tbl[0] = kn02xa_io_int; *imr = 0; /* @@ -345,6 +320,7 @@ cpu_mask_tbl[5] = IE_IRQ5; cpu_irq_nr[5] = FPU; + dec_halt_init(&irq10); } /* dec_init_kn02ba */ /* @@ -355,14 +331,15 @@ /* * Setup some memory addresses. FIXME: probably incomplete! */ + ioasic_base = (void *) KN02XA_IOASIC_BASE; dec_rtc_base = (char *) KN02XA_RTC_BASE; - isr = (volatile unsigned int *) KN02XA_SIR_ADDR; - imr = (volatile unsigned int *) KN02XA_SIRM_ADDR; + isr = (void *) KN02XA_IOASIC_REG(SIR); + imr = (void *) KN02XA_IOASIC_REG(SIMR); /* * Setup IOASIC interrupt */ - cpu_ivec_tbl[1] = kn02ba_io_int; + cpu_ivec_tbl[1] = kn02xa_io_int; cpu_irq_nr[1] = -1; cpu_mask_tbl[1] = IE_IRQ3; *imr = 0; @@ -420,6 +397,7 @@ cpu_mask_tbl[4] = IE_IRQ5; cpu_irq_nr[4] = FPU; + dec_halt_init(&irq10); } /* dec_init_kn02ca */ /* @@ -430,9 +408,10 @@ /* * Setup some memory addresses. FIXME: probably incomplete! */ + ioasic_base = (void *) KN03_IOASIC_BASE; dec_rtc_base = (char *) KN03_RTC_BASE; - isr = (volatile unsigned int *) KN03_SIR_ADDR; - imr = (volatile unsigned int *) KN03_SIRM_ADDR; + isr = (void *) KN03_IOASIC_REG(SIR); + imr = (void *) KN03_IOASIC_REG(SIMR); /* * Setup IOASIC interrupt @@ -500,4 +479,5 @@ cpu_mask_tbl[4] = IE_IRQ5; cpu_irq_nr[4] = FPU; + dec_halt_init(&irq10); } /* dec_init_kn03 */ Index: time.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/time.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- time.c 14 Jan 2001 19:28:59 -0000 1.1.1.1 +++ time.c 10 Apr 2002 14:38:05 -0000 1.2 @@ -1,8 +1,8 @@ - /* - * linux/arch/mips/kernel/time.c + * linux/arch/mips/dec/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds + * Copyright (C) 2000 Maciej W. Rozycki * * This file contains the time handling details for PC-style clocks as * found in some MIPS systems. @@ -17,14 +17,22 @@ #include <linux/mm.h> #include <linux/interrupt.h> +#include <asm/cpu.h> #include <asm/bootinfo.h> #include <asm/mipsregs.h> #include <asm/io.h> #include <asm/irq.h> +#include <asm/dec/machtype.h> +#include <asm/dec/ioasic.h> +#include <asm/dec/ioasic_addrs.h> #include <linux/mc146818rtc.h> #include <linux/timex.h> +#include <asm/div64.h> + +extern void (*board_time_init)(struct irqaction *irq); + extern volatile unsigned long wall_jiffies; extern rwlock_t xtime_lock; @@ -36,12 +44,22 @@ /* This is for machines which generate the exact clock. */ #define USECS_PER_JIFFY (1000000/HZ) +#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff) /* Cycle counter value at the previous timer interrupt.. */ static unsigned int timerhi, timerlo; /* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ +static unsigned long cached_quotient = 0; + +/* Last jiffy when do_fast_gettimeoffset() was called. */ +static unsigned long last_jiffies = 0; + +/* * On MIPS only R4000 and better have a cycle counter. * * FIXME: Does playing with the RP bit in c0_status interfere with this code? @@ -50,45 +68,34 @@ { u32 count; unsigned long res, tmp; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies = 0; unsigned long quotient; - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient = 0; - tmp = jiffies; quotient = cached_quotient; - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r"(quotient) - :"r"(timerhi), - "m"(timerlo), - "r"(tmp), - "r"(USECS_PER_JIFFY) - :"$1"); + if (last_jiffies != tmp) { + last_jiffies = tmp; + if (last_jiffies != 0) { + unsigned long r0; + __asm__(".set push\n\t" + ".set mips3\n\t" + "lwu %0,%3\n\t" + "dsll32 %1,%2,0\n\t" + "or %1,%1,%0\n\t" + "ddivu $0,%1,%4\n\t" + "mflo %1\n\t" + "dsll32 %0,%5,0\n\t" + "or %0,%0,%6\n\t" + "ddivu $0,%0,%1\n\t" + "mflo %0\n\t" + ".set pop" + : "=&r" (quotient), "=&r" (r0) + : "r" (timerhi), "m" (timerlo), + "r" (tmp), "r" (USECS_PER_JIFFY), + "r" (USECS_PER_JIFFY_FRAC)); cached_quotient = quotient; + } } /* Get last timer tick in absolute kernel time */ count = read_32bit_cp0_register(CP0_COUNT); @@ -97,11 +104,9 @@ count -= timerlo; //printk("count: %08lx, %08lx:%08lx\n", count, timerhi, timerlo); - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r"(res) - :"r"(count), - "r"(quotient)); + __asm__("multu %2,%3" + : "=l" (tmp), "=h" (res) + : "r" (count), "r" (quotient)); /* * Due to possible jiffies inconsistencies, we need to check @@ -113,6 +118,47 @@ return res; } +static unsigned long do_ioasic_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + unsigned long quotient; + + tmp = jiffies; + + quotient = cached_quotient; + + if (last_jiffies != tmp) { + last_jiffies = tmp; + if (last_jiffies != 0) { + unsigned long r0; + do_div64_32(r0, timerhi, timerlo, tmp); + do_div64_32(quotient, USECS_PER_JIFFY, + USECS_PER_JIFFY_FRAC, r0); + cached_quotient = quotient; + } + } + /* Get last timer tick in absolute kernel time */ + count = ioasic_read(FCTR); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; +//printk("count: %08x, %08x:%08x\n", count, timerhi, timerlo); + + __asm__("multu %2,%3" + : "=l" (tmp), "=h" (res) + : "r" (count), "r" (quotient)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY - 1; + + return res; +} + /* This function must be called with interrupts disabled * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs * @@ -170,8 +216,8 @@ tv->tv_usec += do_gettimeoffset(); /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. */ if (jiffies - wall_jiffies) tv->tv_usec += USECS_PER_JIFFY; @@ -187,6 +233,7 @@ void do_settimeofday(struct timeval *tv) { write_lock_irq(&xtime_lock); + /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. @@ -199,10 +246,13 @@ tv->tv_usec += 1000000; tv->tv_sec--; } + xtime = *tv; - time_state = TIME_BAD; - time_maxerror = MAXPHASE; - time_esterror = MAXPHASE; + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + write_unlock_irq(&xtime_lock); } @@ -307,13 +357,16 @@ * called as close as possible to 500 ms before the new second starts. */ read_lock(&xtime_lock); - if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec > 500000 - (tick >> 1) && - xtime.tv_usec < 500000 + (tick >> 1)) + if ((time_status & STA_UNSYNC) == 0 + && xtime.tv_sec > last_rtc_update + 660 + && xtime.tv_usec >= 500000 - tick / 2 + && xtime.tv_usec <= 500000 + tick / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; + } /* As we return to user mode fire off the other CPU schedulers.. this is basically because we don't yet share IRQ's around. This message is rigged to be safe on the 386 - basically it's a hack, so don't look @@ -334,66 +387,50 @@ timerhi += (count < timerlo); /* Wrap around */ timerlo = count; - timer_interrupt(irq, dev_id, regs); - - if (!jiffies) { + if (jiffies == ~0) { /* - * If jiffies has overflowed in this timer_interrupt we must + * If jiffies is to overflow in this timer_interrupt we must * update the timer[hi]/[lo] to make do_fast_gettimeoffset() * quotient calc still valid. -arca */ + write_32bit_cp0_register(CP0_COUNT, 0); timerhi = timerlo = 0; } -} -char cyclecounter_available; + timer_interrupt(irq, dev_id, regs); +} -static inline void init_cycle_counter(void) +static void ioasic_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - switch (mips_cputype) { - case CPU_UNKNOWN: - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3041: - case CPU_R3051: - case CPU_R3052: - case CPU_R3081: - case CPU_R3081E: - case CPU_R6000: - case CPU_R6000A: - case CPU_R8000: /* Not shure about that one, play safe */ - cyclecounter_available = 0; - break; - case CPU_R4000PC: - case CPU_R4000SC: - case CPU_R4000MC: - case CPU_R4200: - case CPU_R4400PC: - case CPU_R4400SC: - case CPU_R4400MC: - case CPU_R4600: - case CPU_R10000: - case CPU_R4300: - case CPU_R4650: - case CPU_R4700: - case CPU_R5000: - case CPU_R5000A: - case CPU_R4640: - case CPU_NEVADA: - cyclecounter_available = 1; - break; + unsigned int count; + + /* + * The free-running counter is 32 bit which is good for about + * 2 minutes, 50 seconds at possible count rates of upto 25MHz. + */ + count = ioasic_read(FCTR); + timerhi += (count < timerlo); /* Wrap around */ + timerlo = count; + + if (jiffies == ~0) { + /* + * If jiffies is to overflow in this timer_interrupt we must + * update the timer[hi]/[lo] to make do_fast_gettimeoffset() + * quotient calc still valid. -arca + */ + ioasic_write(FCTR, 0); + timerhi = timerlo = 0; } + + timer_interrupt(irq, dev_id, regs); } struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; -void (*board_time_init) (struct irqaction * irq); - void __init time_init(void) { - unsigned int year, mon, day, hour, min, sec; + unsigned int year, mon, day, hour, min, sec, real_year; int i; /* The Linux interpretation of the CMOS clock register contents: @@ -425,23 +462,26 @@ BCD_TO_BIN(year); } /* - * The DECstation RTC is used as a TOY (Time Of Year). - * The PROM will reset the year to either '70, '71 or '72. - * This hack will only work until Dec 31 2001. + * The PROM will reset the year to either '72 or '73. + * Therefore we store the real year separately, in one + * of unused BBU RAM locations. */ - year += 1928; + real_year = CMOS_READ(RTC_DEC_YEAR); + year += real_year - 72 + 2000; write_lock_irq(&xtime_lock); xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_usec = 0; write_unlock_irq(&xtime_lock); - init_cycle_counter(); - - if (cyclecounter_available) { + if (mips_cpu.options & MIPS_CPU_COUNTER) { write_32bit_cp0_register(CP0_COUNT, 0); do_gettimeoffset = do_fast_gettimeoffset; irq0.handler = r4k_timer_interrupt; - } + } else if (IOASIC) { + ioasic_write(FCTR, 0); + do_gettimeoffset = do_ioasic_gettimeoffset; + irq0.handler = ioasic_timer_interrupt; + } board_time_init(&irq0); } Index: wbflush.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/mips/dec/wbflush.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- wbflush.c 14 Jan 2001 19:28:59 -0000 1.1.1.1 +++ wbflush.c 10 Apr 2002 14:38:05 -0000 1.2 @@ -103,8 +103,6 @@ { } -#ifdef EXPORT_SYMTAB #include <linux/module.h> EXPORT_SYMBOL(__wbflush); -#endif --- serial.c DELETED --- |