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 ---
|