From aba4e552a2f2c1492441acbccedd8e0a4c53f916 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 18 Feb 2000 22:06:10 +0000 Subject: Merge with Linux 2.3.43. --- arch/alpha/lib/csum_ipv6_magic.S | 42 +- arch/i386/config.in | 2 +- arch/i386/kernel/smpboot.c | 11 +- arch/m68k/amiga/amiints.c | 6 +- arch/m68k/atari/debug.c | 4 - arch/m68k/bvme6000/config.c | 1 + arch/m68k/kernel/signal.c | 2 + arch/m68k/kernel/traps.c | 23 - arch/m68k/mac/debug.c | 4 - arch/m68k/mvme147/config.c | 1 + arch/m68k/mvme16x/config.c | 1 + arch/sparc/Makefile | 10 +- arch/sparc/ap1000/Makefile | 20 - arch/sparc/ap1000/apinline.h | 86 --- arch/sparc/ap1000/aplib.c | 496 -------------- arch/sparc/ap1000/apmmu.c | 1144 ------------------------------- arch/sparc/ap1000/approm.c | 148 ---- arch/sparc/ap1000/bnet.c | 1205 --------------------------------- arch/sparc/ap1000/dma.c | 74 -- arch/sparc/ap1000/hw.c | 200 ------ arch/sparc/ap1000/irq.c | 64 -- arch/sparc/ap1000/kgdb.c | 78 --- arch/sparc/ap1000/mpp.c | 83 --- arch/sparc/ap1000/msc.c | 1262 ----------------------------------- arch/sparc/ap1000/sync.c | 55 -- arch/sparc/ap1000/timer.c | 125 ---- arch/sparc/ap1000/tnet.c | 708 -------------------- arch/sparc/ap1000/util.c | 436 ------------ arch/sparc/config.in | 67 +- arch/sparc/defconfig | 19 +- arch/sparc/kernel/head.S | 9 +- arch/sparc/kernel/ioport.c | 2 +- arch/sparc/kernel/irq.c | 8 +- arch/sparc/kernel/process.c | 5 +- arch/sparc/kernel/setup.c | 15 +- arch/sparc/kernel/sparc_ksyms.c | 2 +- arch/sparc/kernel/sys_sparc.c | 11 +- arch/sparc/kernel/sys_sunos.c | 2 +- arch/sparc/kernel/systbls.S | 8 +- arch/sparc/kernel/time.c | 19 +- arch/sparc/mm/Makefile | 5 +- arch/sparc/mm/asyncd.c | 290 -------- arch/sparc/mm/init.c | 11 +- arch/sparc/mm/loadmmu.c | 7 +- arch/sparc/prom/bootstr.c | 7 +- arch/sparc/prom/console.c | 15 +- arch/sparc/prom/devops.c | 5 +- arch/sparc/prom/init.c | 10 +- arch/sparc/prom/memory.c | 15 +- arch/sparc/prom/mp.c | 6 +- arch/sparc/prom/printf.c | 6 +- arch/sparc64/config.in | 2 +- arch/sparc64/defconfig | 9 +- arch/sparc64/kernel/binfmt_elf32.c | 2 +- arch/sparc64/kernel/dtlb_backend.S | 4 +- arch/sparc64/kernel/dtlb_base.S | 4 +- arch/sparc64/kernel/dtlb_prot.S | 4 +- arch/sparc64/kernel/ioctl32.c | 2 +- arch/sparc64/kernel/iommu_common.c | 2 +- arch/sparc64/kernel/itlb_base.S | 4 +- arch/sparc64/kernel/pci_iommu.c | 2 +- arch/sparc64/kernel/pci_psycho.c | 2 +- arch/sparc64/kernel/pci_sabre.c | 2 +- arch/sparc64/kernel/sbus.c | 2 +- arch/sparc64/kernel/sparc64_ksyms.c | 12 +- arch/sparc64/kernel/starfire.c | 4 +- arch/sparc64/kernel/sys_sparc.c | 2 +- arch/sparc64/kernel/sys_sunos32.c | 2 +- arch/sparc64/kernel/systbls.S | 6 +- arch/sparc64/lib/debuglocks.c | 4 +- arch/sparc64/lib/memscan.S | 4 +- arch/sparc64/mm/Makefile | 4 +- arch/sparc64/mm/asyncd.c | 283 -------- arch/sparc64/solaris/misc.c | 2 +- 74 files changed, 156 insertions(+), 7043 deletions(-) delete mode 100644 arch/sparc/ap1000/Makefile delete mode 100644 arch/sparc/ap1000/apinline.h delete mode 100644 arch/sparc/ap1000/aplib.c delete mode 100644 arch/sparc/ap1000/apmmu.c delete mode 100644 arch/sparc/ap1000/approm.c delete mode 100644 arch/sparc/ap1000/bnet.c delete mode 100644 arch/sparc/ap1000/dma.c delete mode 100644 arch/sparc/ap1000/hw.c delete mode 100644 arch/sparc/ap1000/irq.c delete mode 100644 arch/sparc/ap1000/kgdb.c delete mode 100644 arch/sparc/ap1000/mpp.c delete mode 100644 arch/sparc/ap1000/msc.c delete mode 100644 arch/sparc/ap1000/sync.c delete mode 100644 arch/sparc/ap1000/timer.c delete mode 100644 arch/sparc/ap1000/tnet.c delete mode 100644 arch/sparc/ap1000/util.c delete mode 100644 arch/sparc/mm/asyncd.c delete mode 100644 arch/sparc64/mm/asyncd.c (limited to 'arch') diff --git a/arch/alpha/lib/csum_ipv6_magic.S b/arch/alpha/lib/csum_ipv6_magic.S index d9ddb6e74..495375a1a 100644 --- a/arch/alpha/lib/csum_ipv6_magic.S +++ b/arch/alpha/lib/csum_ipv6_magic.S @@ -4,7 +4,7 @@ * * unsigned short csum_ipv6_magic(struct in6_addr *saddr, * struct in6_addr *daddr, - * __u16 len, + * __u32 len, * unsigned short proto, * unsigned int csum); */ @@ -18,54 +18,74 @@ csum_ipv6_magic: ldq $0,0($16) # e0 : load src & dst addr words zapnot $20,15,$20 # .. e1 : zero extend incoming csum - extwh $18,7,$4 # e0 : byte swap len & proto while we wait + extqh $18,7,$4 # e0 : byte swap len & proto while we wait ldq $1,8($16) # .. e1 : - extbl $18,1,$18 # e0 : + + extbl $18,1,$5 # e0 : ldq $2,0($17) # .. e1 : - extwh $19,7,$5 # e0 : + extbl $18,2,$6 # e0 : ldq $3,8($17) # .. e1 : - extbl $19,1,$19 # e0 : - or $18,$4,$18 # .. e1 : - addq $20,$0,$20 # e0 : begin summing the words - or $19,$5,$19 # .. e1 : - sll $18,48,$18 # e0 : + + extbl $18,3,$18 # e0 : + sra $4,32,$4 # e0 : + sll $5,16,$5 # e0 : + addq $20,$0,$20 # .. e1 : begin summing the words + + sll $6,8,$6 # e0 : cmpult $20,$0,$0 # .. e1 : + extwh $19,7,$7 # e0 : + or $4,$18,$18 # .. e1 : + + extbl $19,1,$19 # e0 : + or $5,$6,$5 # .. e1 : + or $18,$5,$18 # e0 : len complete + or $19,$7,$19 # .. e1 : + sll $19,48,$19 # e0 : addq $20,$1,$20 # .. e1 : - sra $18,32,$18 # e0 : len complete - cmpult $20,$1,$1 # .. e1 : sra $19,32,$19 # e0 : proto complete + cmpult $20,$1,$1 # .. e1 : + + nop # e0 : addq $20,$2,$20 # .. e1 : cmpult $20,$2,$2 # e0 : addq $20,$3,$20 # .. e1 : + cmpult $20,$3,$3 # e0 : addq $20,$18,$20 # .. e1 : cmpult $20,$18,$18 # e0 : addq $20,$19,$20 # .. e1 : + cmpult $20,$19,$19 # e0 : addq $0,$1,$0 # .. e1 : merge the carries back into the csum addq $2,$3,$2 # e0 : addq $18,$19,$18 # .. e1 : + addq $0,$2,$0 # e0 : addq $20,$18,$20 # .. e1 : addq $0,$20,$0 # e0 : unop # : + extwl $0,2,$2 # e0 : begin folding the 64-bit value zapnot $0,3,$3 # .. e1 : extwl $0,4,$1 # e0 : addq $2,$3,$3 # .. e1 : + extwl $0,6,$0 # e0 : addq $3,$1,$3 # .. e1 : addq $0,$3,$0 # e0 : unop # : + extwl $0,2,$1 # e0 : fold 18-bit value zapnot $0,3,$0 # .. e1 : addq $0,$1,$0 # e0 : unop # : + extwl $0,2,$1 # e0 : fold 17-bit value zapnot $0,3,$0 # .. e1 : addq $0,$1,$0 # e0 : not $0,$0 # e1 : and compliment. + zapnot $0,3,$0 # e0 : ret # .. e1 : diff --git a/arch/i386/config.in b/arch/i386/config.in index 0dda4d49f..2377c24b7 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -22,7 +22,7 @@ choice 'Processor family' \ 586/K5/5x86/6x86 CONFIG_M586 \ Pentium/TSC CONFIG_M586TSC \ PPro/6x86MX CONFIG_M686 \ - K6/II/II CONFIG_MK6 \ + K6/II/III CONFIG_MK6 \ Athlon CONFIG_MK7" PPro # # Define implied options from the CPU selection here diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 3ff5cc002..50b743a99 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -710,7 +710,8 @@ extern unsigned long cpu_hz; static void smp_tune_scheduling (void) { - unsigned long cachesize; + unsigned long cachesize; /* kB */ + unsigned long bandwidth = 350; /* MB/s */ /* * Rough estimation for SMP scheduling, this is the number of * cycles it takes for a fully memory-limited process to flush @@ -731,10 +732,12 @@ static void smp_tune_scheduling (void) return; } else { cachesize = boot_cpu_data.x86_cache_size; - if (cachesize == -1) - cachesize = 8; /* Pentiums */ + if (cachesize == -1) { + cachesize = 16; /* Pentiums, 2x8kB cache */ + bandwidth = 100; + } - cacheflush_time = cpu_hz/1024*cachesize/5000; + cacheflush_time = (cpu_hz>>20) * (cachesize<<10) / bandwidth; } printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 209813dfb..099119178 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -364,7 +364,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) intena = ami_intena_vals[irq]; custom.intreq = intena; - /* serve first fast handlers - there can only be one of these */ + /* serve fast handler if present - there can only be one of these */ node = ami_irq_list[irq]; /* @@ -392,7 +392,11 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) */ custom.intena = intena; save_flags(flags); +#if 0 /* def CPU_M68060_ONLY */ sti(); +#else + restore_flags((flags & ~0x0700) | (fp->sr & 0x0700)); +#endif slow_nodes = node; for (;;) { diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c index e14c97e42..e30cb4e55 100644 --- a/arch/m68k/atari/debug.c +++ b/arch/m68k/atari/debug.c @@ -311,10 +311,6 @@ void atari_init_midi_port( int cflag ) void __init atari_debug_init(void) { -#ifdef CONFIG_KGDB - /* the m68k_debug_device is used by the GDB stub, do nothing here */ - return; -#endif if (!strcmp( m68k_debug_device, "ser" )) { /* defaults to ser2 for a Falcon and ser1 otherwise */ strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" ); diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index bbe808d3f..b1b245ec2 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c @@ -132,6 +132,7 @@ void __init config_bvme6000(void) bvme6000_set_vectors(); #endif + mach_max_dma_address = 0xffffffff; mach_sched_init = bvme6000_sched_init; mach_keyb_init = bvme6000_keyb_init; mach_kbdrate = bvme6000_kbdrate; diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index 555b39612..d795c71ad 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1048,6 +1049,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) info.si_code = SI_USER; info.si_pid = current->p_pptr->pid; info.si_uid = current->p_pptr->uid; + info.si_uid16 = high2lowuid(current->p_pptr->uid); } /* If the (new) signal is now blocked, requeue it. */ diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index db298c997..5fd9dc0a7 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -37,9 +37,6 @@ #include #include #include -#ifdef CONFIG_KGDB -#include -#endif /* assembler routines */ asmlinkage void system_call(void); @@ -766,11 +763,6 @@ int kstack_depth_to_print = 48; static void dump_stack(struct frame *fp) { -#ifdef CONFIG_KGDB - /* This will never return to here, if kgdb has been initialized. And if - * it returns from there, then to where the error happened... */ - enter_kgdb( &fp->ptregs ); -#else unsigned long *stack, *endstack, addr, module_start, module_end; extern char _start, _etext; int i; @@ -868,15 +860,10 @@ static void dump_stack(struct frame *fp) for (i = 0; i < 10; i++) printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]); printk ("\n"); -#endif } void bad_super_trap (struct frame *fp) { -#ifdef CONFIG_KGDB - /* Save the register dump if we'll enter kgdb anyways */ - if (!kgdb_initialized) { -#endif console_verbose(); if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0])) printk ("*** %s *** FORMAT=%X\n", @@ -906,9 +893,6 @@ void bad_super_trap (struct frame *fp) fp->ptregs.pc); } printk ("Current process id is %d\n", current->pid); -#ifdef CONFIG_KGDB - } -#endif die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); } @@ -1037,10 +1021,6 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr) if (!(fp->sr & PS_S)) return; -#ifdef CONFIG_KGDB - /* Save the register dump if we'll enter kgdb anyways */ - if (!kgdb_initialized) { -#endif console_verbose(); printk("%s: %08x\n",str,nr); printk("PC: [<%08lx>]\nSR: %04x SP: %p a2: %08lx\n", @@ -1052,9 +1032,6 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr) printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, PAGE_SIZE+(unsigned long)current); -#ifdef CONFIG_KGDB - } -#endif dump_stack((struct frame *)fp); do_exit(SIGSEGV); } diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index 98cb2a695..fa3910b5e 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -397,10 +397,6 @@ void mac_init_sccb_port( int cflag ) void __init mac_debug_init(void) { -#ifdef CONFIG_KGDB - /* the m68k_debug_device is used by the GDB stub, do nothing here */ - return; -#endif #ifdef DEBUG_SERIAL if ( !strcmp( m68k_debug_device, "ser" ) || !strcmp( m68k_debug_device, "ser1" )) { diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index c27a18279..d48a0201b 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c @@ -101,6 +101,7 @@ static int mvme147_get_hardware_list(char *buffer) void __init config_mvme147(void) { + mach_max_dma_address = 0x01000000; mach_sched_init = mvme147_sched_init; mach_keyb_init = mvme147_keyb_init; mach_kbdrate = mvme147_kbdrate; diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 3c93562f9..83a0d5297 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c @@ -145,6 +145,7 @@ void __init config_mvme16x(void) p_bdid p = &mvme_bdid; char id[40]; + mach_max_dma_address = 0xffffffff; mach_sched_init = mvme16x_sched_init; mach_keyb_init = mvme16x_keyb_init; mach_kbdrate = mvme16x_kbdrate; diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index cb7ab8775..dec2105d8 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.44 1999/08/19 06:22:20 jj Exp $ +# $Id: Makefile,v 1.45 2000/01/29 01:08:48 anton Exp $ # sparc/Makefile # # Makefile for the architecture dependent flags and dependencies on the @@ -44,14 +44,6 @@ CORE_FILES := arch/sparc/kernel/kernel.o arch/sparc/mm/mm.o $(CORE_FILES) \ LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TOPDIR)/arch/sparc/prom/promlib.a \ $(TOPDIR)/arch/sparc/lib/lib.a -ifdef CONFIG_AP1000 -SUBDIRS := $(SUBDIRS) arch/sparc/ap1000 mpp -CORE_FILES := $(TOPDIR)/arch/sparc/ap1000/ap1000lib.o \ - $(TOPDIR)/mpp/mpplib.o $(CORE_FILES) -DRIVERS := $(DRIVERS) drivers/ap1000/ap1000.a -CFLAGS := $(CFLAGS) -D__MPP__=1 -endif - # This one has to come last SUBDIRS += arch/sparc/boot CORE_FILES_NO_BTFIX := $(CORE_FILES) diff --git a/arch/sparc/ap1000/Makefile b/arch/sparc/ap1000/Makefile deleted file mode 100644 index f070f7675..000000000 --- a/arch/sparc/ap1000/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Makefile for the AP1000 files in the Linux kernel -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -.S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s -.S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o - -all: ap1000lib.o - -O_TARGET := ap1000lib.o -O_OBJS := bnet.o timer.o util.o dma.o kgdb.o irq.o \ - msc.o hw.o tnet.o sync.o mpp.o \ - apmmu.o aplib.o approm.o - -include $(TOPDIR)/Rules.make diff --git a/arch/sparc/ap1000/apinline.h b/arch/sparc/ap1000/apinline.h deleted file mode 100644 index d8170b59e..000000000 --- a/arch/sparc/ap1000/apinline.h +++ /dev/null @@ -1,86 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* inline utilities to support the AP1000 code */ - -#if 0 -/* MMU bypass access */ - -static inline unsigned long phys_9_in(unsigned long paddr) -{ - unsigned long word; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (word) : - "r" (paddr), "i" (0x29) : - "memory"); - return word; -} - -static inline void phys_9_out(unsigned long paddr, unsigned long word) -{ - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (word), "r" (paddr), "i" (0x29) : - "memory"); -} - -static inline unsigned long phys_b_in(unsigned long paddr) -{ - unsigned long word; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (word) : - "r" (paddr), "i" (0x2b) : - "memory"); - return word; -} - -static inline void phys_b_out(unsigned long paddr, unsigned long word) -{ - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (word), "r" (paddr), "i" (0x2b) : - "memory"); -} - -static inline unsigned long phys_c_in(unsigned long paddr) -{ - unsigned long word; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (word) : - "r" (paddr), "i" (0x2b) : - "memory"); - return word; -} - -static inline void phys_c_out(unsigned long paddr, unsigned long word) -{ - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (word), "r" (paddr), "i" (0x2b) : - "memory"); -} - -#undef BIF_IN -#undef BIF_OUT -#undef DMA_IN -#undef DMA_OUT -#undef MSC_IN -#undef MSC_OUT -#undef MC_IN -#undef MC_OUT - -#define BIF_IN(reg) phys_9_in(reg) -#define BIF_OUT(reg,v) phys_9_out(reg,v) -#define DMA_IN(reg) phys_9_in(reg) -#define DMA_OUT(reg,v) phys_9_out(reg,v) -#define MC_IN(reg) phys_b_in((reg) - MC_BASE0) -#define MC_OUT(reg,v) phys_b_out((reg) - MC_BASE0,v) -#define MSC_IN(reg) phys_c_in((reg) - MSC_BASE0) -#define MSC_OUT(reg,v) phys_c_out((reg) - MSC_BASE0,v) -#endif - - diff --git a/arch/sparc/ap1000/aplib.c b/arch/sparc/ap1000/aplib.c deleted file mode 100644 index 4e476aba3..000000000 --- a/arch/sparc/ap1000/aplib.c +++ /dev/null @@ -1,496 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ - -/* kernel based aplib. - - This was initially implemented in user space, but we eventually - relented when we discovered some really nasty MSC hardware bugs and - decided to disallow access to the device registers by users. Pity :-( - - Andrew Tridgell, November 1996 -*/ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - #include -#include -#include -#include - - -extern int *tnet_rel_cid_table; -extern unsigned _cid, _ncel, _ncelx, _ncely, _cidx, _cidy; - - -/* this is used to stop the task hogging the MSC while paging in data */ -static inline void page_in(char *addr,long size) -{ - unsigned sum = 0; - while (size > 0) { - sum += *(volatile char *)addr; - addr += PAGE_SIZE; - size -= PAGE_SIZE; - } -} - - -/* this sets up the aplib structures using info passed in from user space - it should only be called once, and should be the first aplib call - it should be followed by APLIB_SYNC - */ -static inline int aplib_init(struct aplib_init *init) -{ - struct aplib_struct *aplib; - int error,i; - int old_uid; - - error = verify_area(VERIFY_READ,init,sizeof(*init)); - if (error) return error; - error = verify_area(VERIFY_READ,init->phys_cells, - sizeof(int)*init->numcells); - if (error) return error; - error = verify_area(VERIFY_WRITE, - init->ringbuffer, - init->ringbuf_size * sizeof(int)); - if (error) return error; - error = verify_area(VERIFY_WRITE, - (char *)APLIB_PAGE_BASE, - APLIB_PAGE_LEN); - if (error) return error; - - if (!MPP_IS_PAR_TASK(current->taskid)) - return -EINVAL; - - if (current->aplib) - return -EINVAL; - - aplib = current->aplib = (struct aplib_struct *)APLIB_PAGE_BASE; - - /* lock the aplib structure in memory */ - old_uid = current->euid; - current->euid = 0; - memset(aplib,0,APLIB_PAGE_LEN); - error = sys_mlock(aplib,APLIB_PAGE_LEN); - current->euid = old_uid; - if (error) { - printk("mlock1 failed\n"); - return error; - } - - /* lock the ringbuffer in memory */ - old_uid = current->euid; - current->euid = 0; - memset(init->ringbuffer,0,init->ringbuf_size*4); - error = sys_mlock(init->ringbuffer,init->ringbuf_size*4); - current->euid = old_uid; - if (error) { - printk("mlock2 failed\n"); - return error; - } - - aplib->ringbuf = init->ringbuffer; - aplib->ringbuf_size = init->ringbuf_size; - aplib->numcells = init->numcells; - aplib->cid = init->cid; - aplib->tid = current->taskid; - aplib->numcells_x = init->numcells_x; - aplib->numcells_y = init->numcells_y; - aplib->cidx = init->cid % init->numcells_x; - aplib->cidy = init->cid / init->numcells_x; - - aplib->physical_cid = (unsigned *)(aplib+1); - aplib->rel_cid = aplib->physical_cid + init->numcells; - - if ((char *)(aplib->rel_cid + init->numcells) > - (char *)(APLIB_PAGE_BASE + APLIB_PAGE_LEN)) { - return -ENOMEM; - } - - memcpy(aplib->physical_cid,init->phys_cells, - sizeof(int)*init->numcells); - - /* initialise the relative cid table */ - for (i=0;inumcells;i++) - aplib->rel_cid[i] = - tnet_rel_cid_table[aplib->physical_cid[i]]; - - return 0; -} - - -/* n == which sync line (ignored) - returns logical or of the stat values across the cells (1 bit resolution) - - This has to be done very carefully as the tasks can startup on the cells - in any order, so we don't know which tasks have started up when this - is called -*/ -static inline int aplib_sync(int n,int stat) -{ - struct aplib_struct *aplib = current->aplib; - static int sync_flags[MPP_NUM_TASKS]; - int i,err; - int tsk = current->taskid; - - stat &= 1; - - if (aplib->numcells < 2) - return stat; - - tsk -= MPP_TASK_BASE; - - if (aplib->cid == 0) { - if ((err=wait_on_int(&sync_flags[tsk], - aplib->numcells-1,5))) - return err; - sync_flags[tsk] = 0; - if (aplib->numcells == _ncel) { - ap_bput(0,0,0,(u_long)&sync_flags[tsk],0); - } else { - for (i=1;inumcells;i++) - ap_put(aplib->physical_cid[i], - 0,0,0,(u_long)&sync_flags[tsk],0); - } - } else { - ap_put(aplib->physical_cid[0], - 0,0,0,(u_long)&sync_flags[tsk],0); - if ((err=wait_on_int(&sync_flags[tsk],1,5))) - return err; - sync_flags[tsk] = 0; - } - - /* I haven't written the xy_ calls yet ... */ - /* aplib_xy_ior(stat,&stat); */ - - return stat; -} - - - -static inline void _putget(unsigned q, - unsigned rcell, - unsigned *src_addr, - unsigned size,unsigned *dest_addr, - unsigned *dest_flag,unsigned *src_flag) -{ - unsigned flags; - volatile unsigned *entry = (volatile unsigned *)q; - - save_flags(flags); cli(); - - *entry = rcell; - *entry = size; - *entry = (unsigned)dest_addr; - *entry = 0; - *entry = (unsigned)dest_flag; - *entry = (unsigned)src_flag; - *entry = (unsigned)src_addr; - *entry = 0; - - restore_flags(flags); -} - - -/* a basic put() operation. Note the avoidance of odd word boundaries - and transfers sizes beyond what the hardware can deal with */ -static inline int aplib_put(struct aplib_putget *put) -{ - int error; - struct aplib_struct *aplib = current->aplib; - - error = verify_area(VERIFY_WRITE,put,sizeof(*put)); - if (error) return error; - - if (put->cid >= aplib->numcells) - return -EINVAL; - - do { - int n; - - if (put->size && (((unsigned)put->src_addr) & 4)) { - n = 1; - } else if (put->size > MAX_PUT_SIZE) { - n = MAX_PUT_SIZE; - } else { - n = put->size; - } - - put->size -= n; - - page_in((char *)put->src_addr,n<<2); - - _putget(MSC_PUT_QUEUE, - aplib->rel_cid[put->cid], - put->src_addr, - n, - put->dest_addr, - put->size?0:put->dest_flag, - put->size?0:put->src_flag); - - put->dest_addr += n; - put->src_addr += n; - } while (put->size); - - if (put->ack) { - aplib->ack_request++; - _putget(MSC_GET_QUEUE, - aplib->rel_cid[put->cid], - 0, 0, 0, - &aplib->ack_flag, 0); - } - - return 0; -} - - -/* a basic get() operation */ -static inline int aplib_get(struct aplib_putget *get) -{ - struct aplib_struct *aplib = current->aplib; - int error = verify_area(VERIFY_WRITE,get,sizeof(*get)); - if (error) return error; - - if (get->cid >= aplib->numcells) - return -EINVAL; - - do { - int n; - - if (get->size && (((unsigned)get->src_addr) & 4)) { - n = 1; - } else if (get->size > MAX_PUT_SIZE) { - n = MAX_PUT_SIZE; - } else { - n = get->size; - } - - get->size -= n; - - page_in((char *)get->dest_addr,n<<2); - - _putget(MSC_GET_QUEUE, - aplib->rel_cid[get->cid], - get->src_addr, - n, - get->dest_addr, - get->size?0:get->dest_flag, - get->size?0:get->src_flag); - - get->dest_addr += n; - get->src_addr += n; - } while (get->size); - - return 0; -} - - -/* we have received a protocol message - now do the get - This function is called from interrupt level with interrupts - disabled - - note that send->size is now in words -*/ -void aplib_bigrecv(unsigned *msgp) -{ - struct aplib_struct *aplib; - struct aplib_send *send = (struct aplib_send *)(msgp+2); - unsigned tid = (msgp[1]&0x3FF); - unsigned cid = (msgp[0]>>22)&0x1FF; - unsigned octx, ctx; - struct task_struct *tsk; - unsigned room; - - tsk = task[tid]; - if (!tsk || !tsk->aplib) - return; - - octx = apmmu_get_context(); - ctx = MPP_TASK_TO_CTX(tid); - if (octx != ctx) - apmmu_set_context(ctx); - aplib = tsk->aplib; - - if (aplib->write_pointer < aplib->read_pointer) - room = aplib->read_pointer - (aplib->write_pointer+1); - else - room = aplib->ringbuf_size - - ((aplib->write_pointer+1)-aplib->read_pointer); - - if (room < (send->size+2)) { - send_sig(SIGLOST,tsk,1); - goto finished; - } - - aplib->ringbuf[aplib->write_pointer++] = send->info1; - aplib->ringbuf[aplib->write_pointer++] = send->info2; - - /* now finally do the get() */ - _putget(MSC_GET_QUEUE, - aplib->rel_cid[cid], - send->src_addr, - send->size, - &aplib->ringbuf[aplib->write_pointer], - &aplib->rbuf_flag2, - send->flag_addr); - - aplib->write_pointer += send->size; - if (aplib->write_pointer >= aplib->ringbuf_size) - aplib->write_pointer -= aplib->ringbuf_size; - -finished: - if (octx != ctx) - apmmu_set_context(octx); -} - - -/* note the 8 byte alignment fix for the MSC bug */ -static inline int aplib_send(struct aplib_send *send) -{ - struct aplib_struct *aplib = current->aplib; - int wordSize; - int byteAlign, byteFix; - u_long src; - u_long info1, info2; - volatile unsigned *q = (volatile unsigned *)MSC_SEND_QUEUE_S; - extern long system_recv_flag; - int error; - unsigned flags, rcell; - unsigned flag_ptr; - - error = verify_area(VERIFY_WRITE,send,sizeof(*send)); - if (error) return error; - - if (send->cid >= aplib->numcells) - return -EINVAL; - - if (send->tag == RBUF_SYSTEM || send->tag == RBUF_BIGSEND) - return -EINVAL; - - error = verify_area(VERIFY_READ,(char *)send->src_addr,send->size); - if (error) return error; - - page_in((char *)send->src_addr,send->size); - - rcell = aplib->rel_cid[send->cid]; - - byteAlign = send->src_addr & 0x3; - byteFix = send->size & 0x3; - - wordSize = (send->size + byteAlign + 3) >> 2; - - src = send->src_addr & ~3; - - /* this handles the MSC alignment bug */ - if (wordSize > 1 && - (src & 4)) { - info1 |= 0x80000000; - src -= 4; - wordSize++; - } - - info1 = (aplib->cid<<22) | (byteFix<<20) | wordSize; - info2 = (send->tag<<28) | (byteAlign<<26) | - (send->type<<10) | aplib->tid; - flag_ptr = (unsigned)&send->flag; - - if (send->size > SMALL_SEND_THRESHOLD) { - send->info1 = info1; - send->info2 = info2; - send->size = wordSize; - send->src_addr = src; - send->flag_addr = (unsigned)&send->flag; - flag_ptr = 0; - - wordSize = sizeof(*send)>>2; - src = (unsigned)send; - - info1 = (aplib->cid<<22) | wordSize; - info2 = (RBUF_BIGSEND<<28) | aplib->tid; - } - - save_flags(flags); cli(); - - *q = rcell; - *q = wordSize; - *q = (u_long)&system_recv_flag; - *q = flag_ptr; - *q = (u_long)src; - *q = 0; - *q = info1; - *q = info2; - - restore_flags(flags); - - return 0; -} - - -static inline int aplib_probe(void) -{ - tnet_check_completion(); - return 0; -} - -static inline int aplib_poll(unsigned counter) -{ - struct aplib_struct *aplib = current->aplib; - - while (counter == aplib->rbuf_flag1 + aplib->rbuf_flag2) { - tnet_check_completion(); - if (current->need_resched) - break; - if (signal_pending(current)) break; - } - return 0; -} - -int sys_aplib(unsigned call,int a1,int a2,int a3,int a4) -{ - - if (!current->aplib && call != APLIB_INIT) - return -EINVAL; - - switch (call) { - case APLIB_INIT: - return aplib_init((struct aplib_init *)a1); - - case APLIB_SYNC: - return aplib_sync(a1,a2); - - case APLIB_PUT: - return aplib_put((struct aplib_putget *)a1); - - case APLIB_GET: - return aplib_get((struct aplib_putget *)a1); - - case APLIB_SEND: - return aplib_send((struct aplib_send *)a1); - - case APLIB_PROBE: - return aplib_probe(); - - case APLIB_POLL: - return aplib_poll((unsigned)a1); - } - - return -EINVAL; -} - - diff --git a/arch/sparc/ap1000/apmmu.c b/arch/sparc/ap1000/apmmu.c deleted file mode 100644 index 425f23b8c..000000000 --- a/arch/sparc/ap1000/apmmu.c +++ /dev/null @@ -1,1144 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* - * apmmu.c: mmu routines for the AP1000 - * - * based on srmmu.c - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -extern void mc_tlb_flush_all(void); - -static void poke_viking(void); -static void viking_flush_tlb_page_for_cbit)(unsigned long page); - -static struct apmmu_stats { - int invall; - int invpg; - int invrnge; - int invmm; -} module_stats; - -static char *apmmu_name; - -static ctxd_t *apmmu_ctx_table_phys; -static ctxd_t *apmmu_context_table; - -static unsigned long ap_mem_size; -static unsigned long mempool; - - -static inline unsigned long apmmu_v2p(unsigned long vaddr) -{ - if (KERNBASE <= vaddr && - (KERNBASE + ap_mem_size > vaddr)) { - return (vaddr - KERNBASE); - } - return 0xffffffffUL; -} - -static inline unsigned long apmmu_p2v(unsigned long paddr) -{ - if (ap_mem_size > paddr) - return (paddr + KERNBASE); - return 0xffffffffUL; -} - -/* In general all page table modifications should use the V8 atomic - * swap instruction. This insures the mmu and the cpu are in sync - * with respect to ref/mod bits in the page tables. - */ -static inline unsigned long apmmu_swap(unsigned long *addr, unsigned long value) -{ - /* the AP1000 has its memory on bus 8, not 0 like suns do */ - if ((value&0xF0000000) == 0) - value |= MEM_BUS_SPACE<<28; - __asm__ __volatile__("swap [%2], %0\n\t" : - "=&r" (value) : - "0" (value), "r" (addr)); - return value; -} - -/* Functions really use this, not apmmu_swap directly. */ -#define apmmu_set_entry(ptr, newentry) \ - apmmu_swap((unsigned long *) (ptr), (newentry)) - - -/* The very generic APMMU page table operations. */ -static unsigned int apmmu_pmd_align(unsigned int addr) { return APMMU_PMD_ALIGN(addr); } -static unsigned int apmmu_pgdir_align(unsigned int addr) { return APMMU_PGDIR_ALIGN(addr); } - -static inline int apmmu_device_memory(unsigned long x) -{ - return ((x & 0xF0000000) != 0); -} - -static unsigned long apmmu_pgd_page(pgd_t pgd) -{ return apmmu_device_memory(pgd_val(pgd))?~0:apmmu_p2v((pgd_val(pgd) & APMMU_PTD_PMASK) << 4); } - -static unsigned long apmmu_pmd_page(pmd_t pmd) -{ return apmmu_device_memory(pmd_val(pmd))?~0:apmmu_p2v((pmd_val(pmd) & APMMU_PTD_PMASK) << 4); } - -static unsigned long apmmu_pte_page(pte_t pte) -{ return apmmu_device_memory(pte_val(pte))?~0:apmmu_p2v((pte_val(pte) & APMMU_PTE_PMASK) << 4); } - -static int apmmu_pte_none(pte_t pte) -{ return !(pte_val(pte) & 0xFFFFFFF); } - -static int apmmu_pte_present(pte_t pte) -{ return ((pte_val(pte) & APMMU_ET_MASK) == APMMU_ET_PTE); } - -static void apmmu_pte_clear(pte_t *ptep) { set_pte(ptep, __pte(0)); } - -static int apmmu_pmd_none(pmd_t pmd) -{ return !(pmd_val(pmd) & 0xFFFFFFF); } - -static int apmmu_pmd_bad(pmd_t pmd) -{ return (pmd_val(pmd) & APMMU_ET_MASK) != APMMU_ET_PTD; } - -static int apmmu_pmd_present(pmd_t pmd) -{ return ((pmd_val(pmd) & APMMU_ET_MASK) == APMMU_ET_PTD); } - -static void apmmu_pmd_clear(pmd_t *pmdp) { set_pte((pte_t *)pmdp, __pte(0)); } - -static int apmmu_pgd_none(pgd_t pgd) -{ return !(pgd_val(pgd) & 0xFFFFFFF); } - -static int apmmu_pgd_bad(pgd_t pgd) -{ return (pgd_val(pgd) & APMMU_ET_MASK) != APMMU_ET_PTD; } - -static int apmmu_pgd_present(pgd_t pgd) -{ return ((pgd_val(pgd) & APMMU_ET_MASK) == APMMU_ET_PTD); } - -static void apmmu_pgd_clear(pgd_t * pgdp) { set_pte((pte_t *)pgdp, __pte(0)); } - -static pte_t apmmu_pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | APMMU_WRITE);} -static pte_t apmmu_pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | APMMU_DIRTY);} -static pte_t apmmu_pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | APMMU_REF);} - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -static pte_t apmmu_mk_pte(unsigned long page, pgprot_t pgprot) -{ return __pte(((apmmu_v2p(page)) >> 4) | pgprot_val(pgprot)); } - -static pte_t apmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot) -{ return __pte(((page) >> 4) | pgprot_val(pgprot)); } - -static pte_t apmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) -{ - return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); -} - -static void apmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) -{ - set_pte((pte_t *)ctxp, (APMMU_ET_PTD | (apmmu_v2p((unsigned long) pgdp) >> 4))); -} - -static void apmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ - set_pte((pte_t *)pgdp, (APMMU_ET_PTD | (apmmu_v2p((unsigned long) pmdp) >> 4))); -} - -static void apmmu_pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - set_pte((pte_t *)pmdp, (APMMU_ET_PTD | (apmmu_v2p((unsigned long) ptep) >> 4))); -} - -static pte_t apmmu_pte_modify(pte_t pte, pgprot_t newprot) -{ - return __pte((pte_val(pte) & APMMU_CHG_MASK) | pgprot_val(newprot)); -} - -/* to find an entry in a top-level page table... */ -static pgd_t *apmmu_pgd_offset(struct mm_struct * mm, unsigned long address) -{ - return mm->pgd + ((address >> APMMU_PGDIR_SHIFT) & (APMMU_PTRS_PER_PGD - 1)); -} - -/* Find an entry in the second-level page table.. */ -static pmd_t *apmmu_pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) apmmu_pgd_page(*dir) + ((address >> APMMU_PMD_SHIFT) & (APMMU_PTRS_PER_PMD - 1)); -} - -/* Find an entry in the third-level page table.. */ -static pte_t *apmmu_pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) apmmu_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (APMMU_PTRS_PER_PTE - 1)); -} - -/* This must update the context table entry for this process. */ -static void apmmu_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) -{ - if(tsk->mm->context != NO_CONTEXT) { - flush_cache_mm(current->mm); - apmmu_ctxd_set(&apmmu_context_table[tsk->mm->context], pgdp); - flush_tlb_mm(current->mm); - } -} - - -/* Accessing the MMU control register. */ -static inline unsigned int apmmu_get_mmureg(void) -{ - unsigned int retval; - __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : - "=r" (retval) : - "i" (ASI_M_MMUREGS)); - return retval; -} - -static inline void apmmu_set_mmureg(unsigned long regval) -{ - __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : : - "r" (regval), "i" (ASI_M_MMUREGS) : "memory"); - -} - -static inline void apmmu_set_ctable_ptr(unsigned long paddr) -{ - paddr = ((paddr >> 4) & APMMU_CTX_PMASK); - paddr |= (MEM_BUS_SPACE<<28); - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (paddr), "r" (APMMU_CTXTBL_PTR), - "i" (ASI_M_MMUREGS) : - "memory"); -} - -static inline void apmmu_flush_whole_tlb(void) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (0x400), /* Flush entire TLB!! */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - -/* These flush types are not available on all chips... */ -static inline void apmmu_flush_tlb_ctx(void) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (0x300), /* Flush TLB ctx.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - -static inline void apmmu_flush_tlb_region(unsigned long addr) -{ - addr &= APMMU_PGDIR_MASK; - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (addr | 0x200), /* Flush TLB region.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - - -static inline void apmmu_flush_tlb_segment(unsigned long addr) -{ - addr &= APMMU_PMD_MASK; - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (addr | 0x100), /* Flush TLB segment.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - -static inline void apmmu_flush_tlb_page(unsigned long page) -{ - page &= PAGE_MASK; - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (page), /* Flush TLB page.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - -static inline unsigned long apmmu_hwprobe(unsigned long vaddr) -{ - unsigned long retval; - - vaddr &= PAGE_MASK; - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); - - return retval; -} - -static inline void apmmu_uncache_page(unsigned long addr) -{ - pgd_t *pgdp = apmmu_pgd_offset(&init_mm, addr); - pmd_t *pmdp; - pte_t *ptep; - - if((pgd_val(*pgdp) & APMMU_ET_MASK) == APMMU_ET_PTE) { - ptep = (pte_t *) pgdp; - } else { - pmdp = apmmu_pmd_offset(pgdp, addr); - if((pmd_val(*pmdp) & APMMU_ET_MASK) == APMMU_ET_PTE) { - ptep = (pte_t *) pmdp; - } else { - ptep = apmmu_pte_offset(pmdp, addr); - } - } - - set_pte(ptep, __pte((pte_val(*ptep) & ~APMMU_CACHE))); - viking_flush_tlb_page_for_cbit(addr); -} - -static inline void apmmu_recache_page(unsigned long addr) -{ - pgd_t *pgdp = apmmu_pgd_offset(&init_mm, addr); - pmd_t *pmdp; - pte_t *ptep; - - if((pgd_val(*pgdp) & APMMU_ET_MASK) == APMMU_ET_PTE) { - ptep = (pte_t *) pgdp; - } else { - pmdp = apmmu_pmd_offset(pgdp, addr); - if((pmd_val(*pmdp) & APMMU_ET_MASK) == APMMU_ET_PTE) { - ptep = (pte_t *) pmdp; - } else { - ptep = apmmu_pte_offset(pmdp, addr); - } - } - set_pte(ptep, __pte((pte_val(*ptep) | APMMU_CACHE))); - viking_flush_tlb_page_for_cbit(addr); -} - -static inline unsigned long apmmu_getpage(void) -{ - unsigned long page = get_free_page(GFP_KERNEL); - - return page; -} - -static inline void apmmu_putpage(unsigned long page) -{ - free_page(page); -} - -/* The easy versions. */ -#define NEW_PGD() (pgd_t *) apmmu_getpage() -#define NEW_PMD() (pmd_t *) apmmu_getpage() -#define NEW_PTE() (pte_t *) apmmu_getpage() -#define FREE_PGD(chunk) apmmu_putpage((unsigned long)(chunk)) -#define FREE_PMD(chunk) apmmu_putpage((unsigned long)(chunk)) -#define FREE_PTE(chunk) apmmu_putpage((unsigned long)(chunk)) - -static pte_t *apmmu_get_pte_fast(void) -{ - return (pte_t *)0; -} - -static pmd_t *apmmu_get_pmd_fast(void) -{ - return (pmd_t *)0; -} - -static pgd_t *apmmu_get_pgd_fast(void) -{ - return (pgd_t *)0; -} - -static void apmmu_free_pte_slow(pte_t *pte) -{ -/* TBD */ -} - -static void apmmu_free_pmd_slow(pmd_t *pmd) -{ -/* TBD */ -} - -static void apmmu_free_pgd_slow(pgd_t *pgd) -{ -/* TBD */ -} - - -/* - * Allocate and free page tables. The xxx_kernel() versions are - * used to allocate a kernel page table - this turns on ASN bits - * if any, and marks the page tables reserved. - */ -static void apmmu_pte_free_kernel(pte_t *pte) -{ - FREE_PTE(pte); -} - -static pte_t *apmmu_pte_alloc_kernel(pmd_t *pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (APMMU_PTRS_PER_PTE - 1); - if(apmmu_pmd_none(*pmd)) { - pte_t *page = NEW_PTE(); - if(apmmu_pmd_none(*pmd)) { - if(page) { - apmmu_pmd_set(pmd, page); - return page + address; - } - apmmu_pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - FREE_PTE(page); - } - if(apmmu_pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - apmmu_pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - return (pte_t *) apmmu_pmd_page(*pmd) + address; -} - -static void apmmu_pmd_free_kernel(pmd_t *pmd) -{ - FREE_PMD(pmd); -} - -static pmd_t *apmmu_pmd_alloc_kernel(pgd_t *pgd, unsigned long address) -{ - address = (address >> APMMU_PMD_SHIFT) & (APMMU_PTRS_PER_PMD - 1); - if(apmmu_pgd_none(*pgd)) { - pmd_t *page; - page = NEW_PMD(); - if(apmmu_pgd_none(*pgd)) { - if(page) { - pgd_set(pgd, page); - return page + address; - } - pgd_set(pgd, (pmd_t *) BAD_PAGETABLE); - return NULL; - } - FREE_PMD(page); - } - if(apmmu_pgd_bad(*pgd)) { - printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd)); - pgd_set(pgd, (pmd_t *) BAD_PAGETABLE); - return NULL; - } - return (pmd_t *) pgd_page(*pgd) + address; -} - -static void apmmu_pte_free(pte_t *pte) -{ - FREE_PTE(pte); -} - -static pte_t *apmmu_pte_alloc(pmd_t * pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (APMMU_PTRS_PER_PTE - 1); - if(apmmu_pmd_none(*pmd)) { - pte_t *page = NEW_PTE(); - if(apmmu_pmd_none(*pmd)) { - if(page) { - apmmu_pmd_set(pmd, page); - return page + address; - } - apmmu_pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - FREE_PTE(page); - } - if(apmmu_pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - apmmu_pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - return ((pte_t *) apmmu_pmd_page(*pmd)) + address; -} - -/* Real three-level page tables on APMMU. */ -static void apmmu_pmd_free(pmd_t * pmd) -{ - FREE_PMD(pmd); -} - -static pmd_t *apmmu_pmd_alloc(pgd_t * pgd, unsigned long address) -{ - address = (address >> APMMU_PMD_SHIFT) & (APMMU_PTRS_PER_PMD - 1); - if(apmmu_pgd_none(*pgd)) { - pmd_t *page = NEW_PMD(); - if(apmmu_pgd_none(*pgd)) { - if(page) { - pgd_set(pgd, page); - return page + address; - } - pgd_set(pgd, (pmd_t *) BAD_PAGETABLE); - return NULL; - } - FREE_PMD(page); - } - if(apmmu_pgd_bad(*pgd)) { - printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd)); - pgd_set(pgd, (pmd_t *) BAD_PAGETABLE); - return NULL; - } - return (pmd_t *) apmmu_pgd_page(*pgd) + address; -} - -static void apmmu_pgd_free(pgd_t *pgd) -{ - FREE_PGD(pgd); -} - -static pgd_t *apmmu_pgd_alloc(void) -{ - return NEW_PGD(); -} - -static void apmmu_pgd_flush(pgd_t *pgdp) -{ -} - -static void apmmu_set_pte_cacheable(pte_t *ptep, pte_t pteval) -{ - apmmu_set_entry(ptep, pte_val(pteval)); -} - -static void apmmu_quick_kernel_fault(unsigned long address) -{ - printk("Kernel faults at addr=0x%08lx\n", address); - printk("PTE=%08lx\n", apmmu_hwprobe((address & PAGE_MASK))); - die_if_kernel("APMMU bolixed...", current->thread.kregs); -} - -static inline void alloc_context(struct task_struct *tsk) -{ - struct mm_struct *mm = tsk->mm; - struct ctx_list *ctxp; - - if (tsk->taskid >= MPP_TASK_BASE) { - mm->context = MPP_CONTEXT_BASE + (tsk->taskid - MPP_TASK_BASE); - return; - } - - ctxp = ctx_free.next; - if(ctxp != &ctx_free) { - remove_from_ctx_list(ctxp); - add_to_used_ctxlist(ctxp); - mm->context = ctxp->ctx_number; - ctxp->ctx_mm = mm; - return; - } - ctxp = ctx_used.next; - if(ctxp->ctx_mm == current->mm) - ctxp = ctxp->next; - if(ctxp == &ctx_used) - panic("out of mmu contexts"); - flush_cache_mm(ctxp->ctx_mm); - flush_tlb_mm(ctxp->ctx_mm); - remove_from_ctx_list(ctxp); - add_to_used_ctxlist(ctxp); - ctxp->ctx_mm->context = NO_CONTEXT; - ctxp->ctx_mm = mm; - mm->context = ctxp->ctx_number; -} - -static inline void free_context(int context) -{ - struct ctx_list *ctx_old; - - if (context >= MPP_CONTEXT_BASE) - return; /* nothing to do! */ - - ctx_old = ctx_list_pool + context; - remove_from_ctx_list(ctx_old); - add_to_free_ctxlist(ctx_old); -} - - -static void apmmu_switch_to_context(struct task_struct *tsk) -{ - if(tsk->mm->context == NO_CONTEXT) { - alloc_context(tsk); - flush_cache_mm(current->mm); - apmmu_ctxd_set(&apmmu_context_table[tsk->mm->context], tsk->mm->pgd); - flush_tlb_mm(current->mm); - } - apmmu_set_context(tsk->mm->context); -} - -static char *apmmu_lockarea(char *vaddr, unsigned long len) -{ - return vaddr; -} - -static void apmmu_unlockarea(char *vaddr, unsigned long len) -{ -} - -struct task_struct *apmmu_alloc_task_struct(void) -{ - return (struct task_struct *) kmalloc(sizeof(struct task_struct), GFP_KERNEL); -} - -static void apmmu_free_task_struct(struct task_struct *tsk) -{ - kfree(tsk); -} - -static void apmmu_null_func(void) -{ -} - -static inline void mc_tlb_flush_all(void) -{ - unsigned long long *tlb4k; - int i; - - tlb4k = (unsigned long long *)MC_MMU_TLB4K; - for (i = MC_MMU_TLB4K_SIZE/4; i > 0; --i) { - tlb4k[0] = 0; - tlb4k[1] = 0; - tlb4k[2] = 0; - tlb4k[3] = 0; - tlb4k += 4; - } -} - -static inline void mc_tlb_flush_page(unsigned vaddr,int ctx) -{ - if (ctx == SYSTEM_CONTEXT || MPP_IS_PAR_CTX(ctx)) { - *(((unsigned long long *)MC_MMU_TLB4K) + ((vaddr>>12)&0xFF)) = 0; - } -} - -static inline void mc_tlb_flush_ctx(int ctx) -{ - unsigned long long *tlb4k = (unsigned long long *)MC_MMU_TLB4K; - if (ctx == SYSTEM_CONTEXT || MPP_IS_PAR_CTX(ctx)) { - int i; - for (i=0; i> 5) & 0xFFF) == ctx) tlb4k[i] = 0; - } -} - -static inline void mc_tlb_flush_region(unsigned start,int ctx) -{ - mc_tlb_flush_ctx(ctx); -} - -static inline void mc_tlb_flush_segment(unsigned start,int ctx) -{ - mc_tlb_flush_ctx(ctx); -} - -static void viking_flush_tlb_all(void) -{ - module_stats.invall++; - flush_user_windows(); - apmmu_flush_whole_tlb(); - mc_tlb_flush_all(); -} - -static void viking_flush_tlb_mm(struct mm_struct *mm) -{ - int octx; - - module_stats.invmm++; - - if(mm->context != NO_CONTEXT) { - flush_user_windows(); - octx = apmmu_get_context(); - if (octx != mm->context) - apmmu_set_context(mm->context); - apmmu_flush_tlb_ctx(); - mc_tlb_flush_ctx(mm->context); - if (octx != mm->context) - apmmu_set_context(octx); - } -} - -static void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) -{ - int octx; - - module_stats.invrnge++; - - if(mm->context != NO_CONTEXT) { - flush_user_windows(); - octx = apmmu_get_context(); - if (octx != mm->context) - apmmu_set_context(mm->context); - if((end - start) < APMMU_PMD_SIZE) { - start &= PAGE_MASK; - while(start < end) { - apmmu_flush_tlb_page(start); - mc_tlb_flush_page(start,mm->context); - start += PAGE_SIZE; - } - } else if((end - start) < APMMU_PGDIR_SIZE) { - start &= APMMU_PMD_MASK; - while(start < end) { - apmmu_flush_tlb_segment(start); - mc_tlb_flush_segment(start,mm->context); - start += APMMU_PMD_SIZE; - } - } else { - start &= APMMU_PGDIR_MASK; - while(start < end) { - apmmu_flush_tlb_region(start); - mc_tlb_flush_region(start,mm->context); - start += APMMU_PGDIR_SIZE; - } - } - if (octx != mm->context) - apmmu_set_context(octx); - } -} - -static void viking_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - int octx; - struct mm_struct *mm = vma->vm_mm; - - module_stats.invpg++; - if(mm->context != NO_CONTEXT) { - flush_user_windows(); - octx = apmmu_get_context(); - if (octx != mm->context) - apmmu_set_context(mm->context); - apmmu_flush_tlb_page(page); - mc_tlb_flush_page(page,mm->context); - if (octx != mm->context) - apmmu_set_context(octx); - } -} - -static void viking_flush_tlb_page_for_cbit(unsigned long page) -{ - apmmu_flush_tlb_page(page); - mc_tlb_flush_page(page,apmmu_get_context()); -} - -/* Some dirty hacks to abstract away the painful boot up init. */ -static inline unsigned long apmmu_early_paddr(unsigned long vaddr) -{ - return (vaddr - KERNBASE); -} - -static inline void apmmu_early_pgd_set(pgd_t *pgdp, pmd_t *pmdp) -{ - set_pte((pte_t *)pgdp, __pte((APMMU_ET_PTD | (apmmu_early_paddr((unsigned long) pmdp) >> 4)))); -} - -static inline void apmmu_early_pmd_set(pmd_t *pmdp, pte_t *ptep) -{ - set_pte((pte_t *)pmdp, __pte((APMMU_ET_PTD | (apmmu_early_paddr((unsigned long) ptep) >> 4)))); -} - -static inline unsigned long apmmu_early_pgd_page(pgd_t pgd) -{ - return ((pgd_val(pgd) & APMMU_PTD_PMASK) << 4) + KERNBASE; -} - -static inline unsigned long apmmu_early_pmd_page(pmd_t pmd) -{ - return ((pmd_val(pmd) & APMMU_PTD_PMASK) << 4) + KERNBASE; -} - -static inline pmd_t *apmmu_early_pmd_offset(pgd_t *dir, unsigned long address) -{ - return (pmd_t *) apmmu_early_pgd_page(*dir) + ((address >> APMMU_PMD_SHIFT) & (APMMU_PTRS_PER_PMD - 1)); -} - -static inline pte_t *apmmu_early_pte_offset(pmd_t *dir, unsigned long address) -{ - return (pte_t *) apmmu_early_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (APMMU_PTRS_PER_PTE - 1)); -} - -static inline void __init apmmu_allocate_ptable_skeleton(unsigned long start, unsigned long end) -{ - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - while(start < end) { - pgdp = apmmu_pgd_offset(&init_mm, start); - if(apmmu_pgd_none(*pgdp)) { - pmdp = sparc_init_alloc(&mempool, APMMU_PMD_TABLE_SIZE); - apmmu_early_pgd_set(pgdp, pmdp); - } - pmdp = apmmu_early_pmd_offset(pgdp, start); - if(apmmu_pmd_none(*pmdp)) { - ptep = sparc_init_alloc(&mempool, APMMU_PTE_TABLE_SIZE); - apmmu_early_pmd_set(pmdp, ptep); - } - start = (start + APMMU_PMD_SIZE) & APMMU_PMD_MASK; - } -} - - -static void __init make_page(unsigned virt_page, unsigned phys_page, unsigned prot) -{ - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - unsigned start = virt_page<<12; - - pgdp = apmmu_pgd_offset(&init_mm, start); - if(apmmu_pgd_none(*pgdp)) { - pmdp = sparc_init_alloc(&mempool, APMMU_PMD_TABLE_SIZE); - apmmu_early_pgd_set(pgdp, pmdp); - } - pmdp = apmmu_early_pmd_offset(pgdp, start); - if(apmmu_pmd_none(*pmdp)) { - ptep = sparc_init_alloc(&mempool, APMMU_PTE_TABLE_SIZE); - apmmu_early_pmd_set(pmdp, ptep); - } - ptep = apmmu_early_pte_offset(pmdp, start); - *ptep = __pte((phys_page<<8) | prot); -} - - -static void __init make_large_page(unsigned virt_page, unsigned phys_page, unsigned prot) -{ - pgd_t *pgdp; - unsigned start = virt_page<<12; - - pgdp = apmmu_pgd_offset(&init_mm, start); - *pgdp = __pgd((phys_page<<8) | prot); -} - - -static void __init ap_setup_mappings(void) -{ - unsigned Srwe = APMMU_PRIV | APMMU_VALID; - unsigned SrweUr = 0x14 | APMMU_VALID; /* weird! */ - - /* LBus */ - make_large_page(0xfb000,0x9fb000,Srwe); - make_large_page(0xff000,0x9ff000,SrweUr); - make_large_page(0xfc000,0x911000,Srwe); - - /* MC Register */ - make_page(0xfa000,0xb00000,SrweUr); - make_page(0xfa001,0xb00001,Srwe); - make_page(0xfa002,0xb00002,Srwe); - make_page(0xfa003,0xb00003,Srwe); - make_page(0xfa004,0xb00004,Srwe); - make_page(0xfa005,0xb00005,Srwe); - make_page(0xfa006,0xb00006,Srwe); - make_page(0xfa007,0xb00007,Srwe); - - /* MSC+ Register */ - make_page(0xfa008,0xc00000,SrweUr); - make_page(0xfa009,0xc00001,Srwe); - make_page(0xfa00a,0xc00002,Srwe); - make_page(0xfa00b,0xc00003,Srwe); - make_page(0xfa00c,0xc00004,Srwe); - make_page(0xfa00d,0xc00005,Srwe); /* RBMPR 0 */ - make_page(0xfa00e,0xc00006,Srwe); /* RBMPR 1 */ - make_page(0xfa00f,0xc00007,Srwe); /* RBMPR 2 */ - - /* user queues */ - make_page(MSC_PUT_QUEUE>>PAGE_SHIFT, 0xa00000,Srwe); - make_page(MSC_GET_QUEUE>>PAGE_SHIFT, 0xa00001,Srwe); - make_page(MSC_SEND_QUEUE>>PAGE_SHIFT, 0xa00040,Srwe); - make_page(MSC_XY_QUEUE>>PAGE_SHIFT, 0xa00640,Srwe); - make_page(MSC_X_QUEUE>>PAGE_SHIFT, 0xa00240,Srwe); - make_page(MSC_Y_QUEUE>>PAGE_SHIFT, 0xa00440,Srwe); - make_page(MSC_XYG_QUEUE>>PAGE_SHIFT, 0xa00600,Srwe); - make_page(MSC_XG_QUEUE>>PAGE_SHIFT, 0xa00200,Srwe); - make_page(MSC_YG_QUEUE>>PAGE_SHIFT, 0xa00400,Srwe); - make_page(MSC_CSI_QUEUE>>PAGE_SHIFT, 0xa02004,Srwe); - make_page(MSC_FOP_QUEUE>>PAGE_SHIFT, 0xa02005,Srwe); - - /* system queues */ - make_page(MSC_PUT_QUEUE_S>>PAGE_SHIFT, 0xa02000,Srwe); /* system put */ - make_page(MSC_CPUT_QUEUE_S>>PAGE_SHIFT, 0xa02020,Srwe); /* system creg put */ - make_page(MSC_GET_QUEUE_S>>PAGE_SHIFT, 0xa02001,Srwe); /* system get */ - make_page(MSC_CGET_QUEUE_S>>PAGE_SHIFT, 0xa02021,Srwe); /* system creg get */ - make_page(MSC_SEND_QUEUE_S>>PAGE_SHIFT, 0xa02040,Srwe); /* system send */ - make_page(MSC_BSEND_QUEUE_S>>PAGE_SHIFT,0xa02640,Srwe); /* system send broad */ - make_page(MSC_XYG_QUEUE_S>>PAGE_SHIFT, 0xa02600,Srwe); /* system put broad */ - make_page(MSC_CXYG_QUEUE_S>>PAGE_SHIFT, 0xa02620,Srwe); /* system put broad */ - - /* Direct queue access entries for refilling the MSC send queue */ - make_page(MSC_SYSTEM_DIRECT>>PAGE_SHIFT, 0xa08000,Srwe); - make_page(MSC_USER_DIRECT>>PAGE_SHIFT, 0xa08001,Srwe); - make_page(MSC_REMOTE_DIRECT>>PAGE_SHIFT, 0xa08002,Srwe); - make_page(MSC_REPLY_DIRECT>>PAGE_SHIFT, 0xa08003,Srwe); - make_page(MSC_REMREPLY_DIRECT>>PAGE_SHIFT, 0xa08004,Srwe); - - /* As above with end-bit set */ - make_page(MSC_SYSTEM_DIRECT_END>>PAGE_SHIFT, 0xa0c000,Srwe); - make_page(MSC_USER_DIRECT_END>>PAGE_SHIFT, 0xa0c001,Srwe); - make_page(MSC_REMOTE_DIRECT_END>>PAGE_SHIFT, 0xa0c002,Srwe); - make_page(MSC_REPLY_DIRECT_END>>PAGE_SHIFT, 0xa0c003,Srwe); - make_page(MSC_REMREPLY_DIRECT_END>>PAGE_SHIFT, 0xa0c004,Srwe); -} - -static void __init map_kernel(void) -{ - int phys; - - /* the AP+ only ever has one bank of memory starting at address 0 */ - ap_mem_size = sp_banks[0].num_bytes; - for (phys=0; phys < sp_banks[0].num_bytes; phys += APMMU_PGDIR_SIZE) - make_large_page((KERNBASE+phys)>>12, - (phys>>12), - APMMU_CACHE|APMMU_PRIV|APMMU_VALID); - init_mm.mmap->vm_start = PAGE_OFFSET; -} - -extern unsigned long free_area_init(unsigned long, unsigned long); -extern unsigned long sparc_context_init(unsigned long, int); - -extern int physmem_mapped_contig; -extern int linux_num_cpus; - -unsigned long __init apmmu_paging_init(unsigned long start_mem, unsigned long end_mem) -{ - int i; - - physmem_mapped_contig = 1; /* for init.c:taint_real_pages() */ - - num_contexts = AP_NUM_CONTEXTS; - mempool = PAGE_ALIGN(start_mem); - memset(swapper_pg_dir, 0, PAGE_SIZE); - - apmmu_allocate_ptable_skeleton(KERNBASE, end_mem); - mempool = PAGE_ALIGN(mempool); - map_kernel(); - ap_setup_mappings(); - - /* the MSC wants this aligned on a 16k boundary */ - apmmu_context_table = - sparc_init_alloc(&mempool, - num_contexts*sizeof(ctxd_t)<0x4000? - 0x4000: - num_contexts*sizeof(ctxd_t)); - apmmu_ctx_table_phys = (ctxd_t *) apmmu_v2p((unsigned long) apmmu_context_table); - for(i = 0; i < num_contexts; i++) - apmmu_ctxd_set(&apmmu_context_table[i], swapper_pg_dir); - - start_mem = PAGE_ALIGN(mempool); - - flush_cache_all(); - apmmu_set_ctable_ptr((unsigned long) apmmu_ctx_table_phys); - flush_tlb_all(); - poke_viking(); - - /* on the AP we don't put the top few contexts into the free - context list as these are reserved for parallel tasks */ - start_mem = sparc_context_init(start_mem, MPP_CONTEXT_BASE); - start_mem = free_area_init(start_mem, end_mem); - - return PAGE_ALIGN(start_mem); -} - -static int apmmu_mmu_info(char *buf) -{ - return sprintf(buf, - "MMU type\t: %s\n" - "invall\t\t: %d\n" - "invmm\t\t: %d\n" - "invrnge\t\t: %d\n" - "invpg\t\t: %d\n" - "contexts\t: %d\n" - , apmmu_name, - module_stats.invall, - module_stats.invmm, - module_stats.invrnge, - module_stats.invpg, - num_contexts - ); -} - -static void apmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) -{ -} - -static void __init poke_viking(void) -{ - unsigned long mreg = apmmu_get_mmureg(); - - mreg |= VIKING_SPENABLE; - mreg |= (VIKING_ICENABLE | VIKING_DCENABLE); - mreg &= ~VIKING_ACENABLE; - mreg &= ~VIKING_SBENABLE; - mreg |= VIKING_TCENABLE; - apmmu_set_mmureg(mreg); -} - -static void __init init_viking(void) -{ - apmmu_name = "TI Viking/AP1000"; - - BTFIXUPSET_CALL(flush_cache_all, apmmu_null_func, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_cache_mm, apmmu_null_func, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_cache_page, apmmu_null_func, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_cache_range, apmmu_null_func, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(flush_tlb_all, viking_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, viking_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, viking_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, viking_flush_tlb_range, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_page_to_ram, apmmu_null_func, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_sig_insns, apmmu_null_func, BTFIXUPCALL_NOP); -} - - -extern unsigned long spwin_mmu_patchme, fwin_mmu_patchme, - tsetup_mmu_patchme, rtrap_mmu_patchme; - -extern unsigned long spwin_srmmu_stackchk, srmmu_fwin_stackchk, - tsetup_srmmu_stackchk, srmmu_rett_stackchk; - -extern unsigned long srmmu_fault; - -#define PATCH_BRANCH(insn, dest) do { \ - iaddr = &(insn); \ - daddr = &(dest); \ - *iaddr = SPARC_BRANCH((unsigned long) daddr, (unsigned long) iaddr); \ - } while(0); - -static void __init patch_window_trap_handlers(void) -{ - unsigned long *iaddr, *daddr; - - PATCH_BRANCH(spwin_mmu_patchme, spwin_srmmu_stackchk); - PATCH_BRANCH(fwin_mmu_patchme, srmmu_fwin_stackchk); - PATCH_BRANCH(tsetup_mmu_patchme, tsetup_srmmu_stackchk); - PATCH_BRANCH(rtrap_mmu_patchme, srmmu_rett_stackchk); - PATCH_BRANCH(sparc_ttable[SP_TRAP_TFLT].inst_three, srmmu_fault); - PATCH_BRANCH(sparc_ttable[SP_TRAP_DFLT].inst_three, srmmu_fault); - PATCH_BRANCH(sparc_ttable[SP_TRAP_DACC].inst_three, srmmu_fault); -} - -/* Load up routines and constants for apmmu */ -void __init ld_mmu_apmmu(void) -{ - /* First the constants */ - BTFIXUPSET_SIMM13(pmd_shift, APMMU_PMD_SHIFT); - BTFIXUPSET_SETHI(pmd_size, APMMU_PMD_SIZE); - BTFIXUPSET_SETHI(pmd_mask, APMMU_PMD_MASK); - BTFIXUPSET_SIMM13(pgdir_shift, APMMU_PGDIR_SHIFT); - BTFIXUPSET_SETHI(pgdir_size, APMMU_PGDIR_SIZE); - BTFIXUPSET_SETHI(pgdir_mask, APMMU_PGDIR_MASK); - - BTFIXUPSET_SIMM13(ptrs_per_pte, APMMU_PTRS_PER_PTE); - BTFIXUPSET_SIMM13(ptrs_per_pmd, APMMU_PTRS_PER_PMD); - BTFIXUPSET_SIMM13(ptrs_per_pgd, APMMU_PTRS_PER_PGD); - - BTFIXUPSET_INT(page_none, pgprot_val(APMMU_PAGE_NONE)); - BTFIXUPSET_INT(page_shared, pgprot_val(APMMU_PAGE_SHARED)); - BTFIXUPSET_INT(page_copy, pgprot_val(APMMU_PAGE_COPY)); - BTFIXUPSET_INT(page_readonly, pgprot_val(APMMU_PAGE_RDONLY)); - BTFIXUPSET_INT(page_kernel, pgprot_val(APMMU_PAGE_KERNEL)); - pg_iobits = APMMU_VALID | APMMU_WRITE | APMMU_REF; - - /* Functions */ - BTFIXUPSET_CALL(get_pte_fast, apmmu_get_pte_fast, BTFIXUPCALL_RETINT(0)); - BTFIXUPSET_CALL(get_pmd_fast, apmmu_get_pmd_fast, BTFIXUPCALL_RETINT(0)); - BTFIXUPSET_CALL(get_pgd_fast, apmmu_get_pgd_fast, BTFIXUPCALL_RETINT(0)); - BTFIXUPSET_CALL(free_pte_slow, apmmu_free_pte_slow, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(free_pmd_slow, apmmu_free_pmd_slow, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(free_pgd_slow, apmmu_free_pgd_slow, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(set_pte, apmmu_set_pte_cacheable, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(switch_to_context, apmmu_switch_to_context, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pte_page, apmmu_pte_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_page, apmmu_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page, apmmu_pgd_page, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(sparc_update_rootmmu_dir, apmmu_update_rootmmu_dir, BTFIXUPCALL_NORM); - - BTFIXUPSET_SETHI(none_mask, 0xF0000000); - - BTFIXUPSET_CALL(pte_present, apmmu_pte_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_clear, apmmu_pte_clear, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pmd_bad, apmmu_pmd_bad, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_present, apmmu_pmd_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_clear, apmmu_pmd_clear, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pgd_none, apmmu_pgd_none, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_bad, apmmu_pgd_bad, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_present, apmmu_pgd_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_clear, apmmu_pgd_clear, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mk_pte, apmmu_mk_pte, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte_phys, apmmu_mk_pte_phys, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte_io, apmmu_mk_pte_io, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_set, apmmu_pgd_set, BTFIXUPCALL_NORM); - - BTFIXUPSET_INT(pte_modify_mask, APMMU_CHG_MASK); - BTFIXUPSET_CALL(pgd_offset, apmmu_pgd_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_offset, apmmu_pmd_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_offset, apmmu_pte_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_free_kernel, apmmu_pte_free_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_free_kernel, apmmu_pmd_free_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_alloc_kernel, apmmu_pte_alloc_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_alloc_kernel, apmmu_pmd_alloc_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_free, apmmu_pte_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_alloc, apmmu_pte_alloc, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_free, apmmu_pmd_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_alloc, apmmu_pmd_alloc, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_free, apmmu_pgd_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_alloc, apmmu_pgd_alloc, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_flush, apmmu_pgd_flush, BTFIXUPCALL_NORM); - - BTFIXUPSET_HALF(pte_writei, APMMU_WRITE); - BTFIXUPSET_HALF(pte_dirtyi, APMMU_DIRTY); - BTFIXUPSET_HALF(pte_youngi, APMMU_REF); - BTFIXUPSET_HALF(pte_wrprotecti, APMMU_WRITE); - BTFIXUPSET_HALF(pte_mkcleani, APMMU_DIRTY); - BTFIXUPSET_HALF(pte_mkoldi, APMMU_REF); - BTFIXUPSET_CALL(pte_mkwrite, apmmu_pte_mkwrite, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_mkdirty, apmmu_pte_mkdirty, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_mkyoung, apmmu_pte_mkyoung, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(update_mmu_cache, apmmu_update_mmu_cache, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(mmu_lockarea, apmmu_lockarea, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_unlockarea, apmmu_unlockarea, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mmu_get_scsi_one, apmmu_null_func, BTFIXUPCALL_RETO0); - BTFIXUPSET_CALL(mmu_get_scsi_sgl, apmmu_null_func, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(mmu_release_scsi_one, apmmu_null_func, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(mmu_release_scsi_sgl, apmmu_null_func, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(mmu_info, apmmu_mmu_info, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_v2p, apmmu_v2p, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_p2v, apmmu_p2v, BTFIXUPCALL_NORM); - - /* Task struct and kernel stack allocating/freeing. */ - BTFIXUPSET_CALL(alloc_task_struct, apmmu_alloc_task_struct, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_task_struct, apmmu_free_task_struct, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(quick_kernel_fault, apmmu_quick_kernel_fault, BTFIXUPCALL_NORM); - - init_viking(); - patch_window_trap_handlers(); -} diff --git a/arch/sparc/ap1000/approm.c b/arch/sparc/ap1000/approm.c deleted file mode 100644 index 4fe956bcb..000000000 --- a/arch/sparc/ap1000/approm.c +++ /dev/null @@ -1,148 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* - * fake a really simple Sun prom for the AP+ - * - */ - -#include -#include -#include -#include -#include -#include - -static struct linux_romvec ap_romvec; -static struct idprom ap_idprom; - -struct property { - char *name; - char *value; - int length; -}; - -struct node { - int level; - struct property *properties; -}; - -struct property null_properties = { NULL, NULL, -1 }; - -struct property root_properties[] = { - {"device_type", "cpu", 4}, - {"idprom", (char *)&ap_idprom, sizeof(ap_idprom)}, - {"banner-name", "Fujitsu AP1000+", 16}, - {NULL, NULL, -1} -}; - -struct node nodes[] = { - { 0, &null_properties }, - { 0, root_properties }, - { -1,&null_properties } -}; - - -static int no_nextnode(int node) -{ - if (nodes[node].level == nodes[node+1].level) - return node+1; - return -1; -} - -static int no_child(int node) -{ - if (nodes[node].level == nodes[node+1].level-1) - return node+1; - return -1; -} - -static struct property *find_property(int node,char *name) -{ - struct property *prop = &nodes[node].properties[0]; - while (prop && prop->name) { - if (strcmp(prop->name,name) == 0) return prop; - prop++; - } - return NULL; -} - -static int no_proplen(int node,char *name) -{ - struct property *prop = find_property(node,name); - if (prop) return prop->length; - return -1; -} - -static int no_getprop(int node,char *name,char *value) -{ - struct property *prop = find_property(node,name); - if (prop) { - memcpy(value,prop->value,prop->length); - return 1; - } - return -1; -} - -static int no_setprop(int node,char *name,char *value,int len) -{ - return -1; -} - -static char *no_nextprop(int node,char *name) -{ - struct property *prop = find_property(node,name); - if (prop) return prop[1].name; - return NULL; -} - - -static struct linux_nodeops ap_nodeops = { - no_nextnode, - no_child, - no_proplen, - no_getprop, - no_setprop, - no_nextprop -}; - - - -static unsigned char calc_idprom_cksum(struct idprom *idprom) -{ - unsigned char cksum, i, *ptr = (unsigned char *)idprom; - - for (i = cksum = 0; i <= 0x0E; i++) - cksum ^= *ptr++; - - return cksum; -} - -static int synch_hook; - - -struct linux_romvec *ap_prom_init(void) -{ - memset(&ap_romvec,0,sizeof(ap_romvec)); - - ap_romvec.pv_romvers = 42; - ap_romvec.pv_nodeops = &ap_nodeops; - ap_romvec.pv_reboot = ap_reboot; - ap_romvec.pv_synchook = &synch_hook; - - ap_idprom.id_format = 1; - ap_idprom.id_sernum = mpp_cid(); - ap_idprom.id_machtype = SM_SUN4M_OBP; - ap_idprom.id_cksum = calc_idprom_cksum(&ap_idprom); - - return &ap_romvec; -} - - - - - diff --git a/arch/sparc/ap1000/bnet.c b/arch/sparc/ap1000/bnet.c deleted file mode 100644 index e87d01181..000000000 --- a/arch/sparc/ap1000/bnet.c +++ /dev/null @@ -1,1205 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* routines to control the AP1000 bif interface. This is the interface - used to talk to the front end processor */ - -#include -#include -#include -#include -#include -#include -#include - -#define NET_DEBUG 0 - -#define DUMMY_MSG_LEN 100 -#define DUMMY_MSG_WAIT 30 - -#define MAX_CELLS 128 - -#define HAVE_BIF() (BIF_IN(BIF_SDCSR) & BIF_SDCSR_BG) -#define BIF_BUSY() (BIF_IN(BIF_SDCSR) & BIF_SDCSR_BB) - -#define SNET_ARBITRATION 0 -#define TOKEN_ARBITRATION 1 - -#define DEBUG(x) - -#if TOKEN_ARBITRATION -static int have_token = 0; -#endif - -extern struct cap_init cap_init; - -static int interrupt_driven = 0; -static int use_dma = 0; -struct pt_regs *bif_pt_regs = NULL; -enum dma_state {DMA_IDLE,DMA_INCOMING,DMA_OUTGOING}; -static enum dma_state dma_state = DMA_IDLE; - -static int net_started = 0; -static int waiting_for_bif = 0; -static int queue_length = 0; - -static int drop_ip_packets = 0; - -#define DMA_THRESHOLD 64 - -static struct cap_request bread_req; - -int tnet_ip_enabled = 1; - -#define BIF_DATA_WAITING() (BIF_IN(BIF_SDCSR) & BIF_SDCSR_RB) - -#define ROUND4(x) (((x) + 3) & -4) - -static void bif_intr_receive(struct cap_request *req1); - - -/* read some data from the bif */ -void read_bif(char *buf,int size) -{ - unsigned *ibuf = (unsigned *)buf; - unsigned avail; - - DEBUG(("|read_bif %d\n",size)); - - if (dma_state != DMA_IDLE) ap_dma_wait(DMA_CH2); - - size = (size+3) >> 2; - - while (size > 4) { - while (!(avail=(BIF_IN(BIF_SDCSR) >> BIF_SDCSR_RB_SHIFT) & 7)) - ; - if (avail & 4) { - ibuf[0] = BIF_IN(BIF_DATA); - ibuf[1] = BIF_IN(BIF_DATA); - ibuf[2] = BIF_IN(BIF_DATA); - ibuf[3] = BIF_IN(BIF_DATA); - size -= 4; ibuf += 4; - continue; - } - - if (avail & 2) { - ibuf[0] = BIF_IN(BIF_DATA); - ibuf[1] = BIF_IN(BIF_DATA); - size -= 2; ibuf += 2; - continue; - } - *ibuf++ = BIF_IN(BIF_DATA); - size--; - } - - while (size--) { - while (!(BIF_IN(BIF_SDCSR) & BIF_SDCSR_RB)) ; - *ibuf++ = BIF_IN(BIF_DATA); - } - - DEBUG(("|read bif done\n")); -} - -/* throw out some data from the bif. This is usually called when we - don't have the resources to handle it immediately */ -void bif_toss(int size) -{ - unsigned flags; - save_flags(flags); cli(); - - DEBUG(("|bif toss %d\n",size)); - - while (size>0) { - while (!BIF_DATA_WAITING()); - BIF_IN(BIF_DATA); - size -= 4; - } - - DEBUG(("|bif toss done\n")); - - restore_flags(flags); -} - - -static void bif_reset_interrupts(void) -{ - BIF_OUT(BIF_INTR,AP_INTR_WENABLE << BIF_INTR_GET_SH); - BIF_OUT(BIF_INTR,AP_INTR_WENABLE << BIF_INTR_HEADER_SH); -} - -static void bif_mask_interrupts(void) -{ - BIF_OUT(BIF_INTR,(AP_INTR_MASK|AP_INTR_WENABLE) << BIF_INTR_GET_SH); - BIF_OUT(BIF_INTR,(AP_INTR_MASK|AP_INTR_WENABLE) << BIF_INTR_HEADER_SH); -} - -static void attn_enable(void) -{ - BIF_OUT(BIF_INTR,AP_INTR_WENABLE << BIF_INTR_ATTN_SH); -} - -static void attn_mask(void) -{ - BIF_OUT(BIF_INTR,(AP_INTR_MASK|AP_INTR_WENABLE) << BIF_INTR_ATTN_SH); -} - - -void ap_bif_status(void) -{ - static int bif_sdcsr; - static int bif_intr; - static int bif_mhocr; - static int bif_x0sk; - static int bif_xsk; - static int bif_xsz; - static int bif_y0sk; - static int bif_ysk; - static int bif_ysz; - static int bif_cx0sk; - static int bif_cxsk; - static int bif_cxsz; - static int bif_cy0sk; - static int bif_cysk; - static int bif_cysz; - static int bif_ttl; - static int bif_cttl; - static int bif_header; - - bif_sdcsr = BIF_IN(BIF_SDCSR); - bif_intr = BIF_IN(BIF_INTR); - bif_mhocr = BIF_IN(BIF_MHOCR); - - bif_x0sk = BIF_IN(BIF_X0SK); - bif_xsk = BIF_IN(BIF_XSK); - bif_xsz = BIF_IN(BIF_XSZ); - bif_y0sk = BIF_IN(BIF_Y0SK); - bif_ysk = BIF_IN(BIF_YSK); - bif_ysz = BIF_IN(BIF_YSZ); - - bif_cx0sk = BIF_IN(BIF_CX0SK); - bif_cxsk = BIF_IN(BIF_CXSK); - bif_cxsz = BIF_IN(BIF_CXSZ); - bif_cy0sk = BIF_IN(BIF_CY0SK); - bif_cysk = BIF_IN(BIF_CYSK); - bif_cysz = BIF_IN(BIF_CYSZ); - - bif_ttl = BIF_IN(BIF_TTL); - bif_cttl = BIF_IN(BIF_CTTL); - bif_header = BIF_IN(BIF_HEADER); - - printk("|\t***** BIF REG. *****\n"); - printk("|\tBIF_SDCSR = %08x ", bif_sdcsr); - if(bif_sdcsr & BIF_SDCSR_CN) printk("|"); - if(bif_sdcsr & BIF_SDCSR_FN) printk("|"); - if(bif_sdcsr & BIF_SDCSR_DE) printk("|"); - if(bif_sdcsr & BIF_SDCSR_DR) printk("|"); - if(bif_sdcsr & BIF_SDCSR_BB) printk("|"); - if(bif_sdcsr & BIF_SDCSR_BR) printk("|"); - if(bif_sdcsr & BIF_SDCSR_BG) printk("|"); - if(bif_sdcsr & BIF_SDCSR_ER) printk("|"); - if(bif_sdcsr & BIF_SDCSR_PE) printk("|"); - printk("|\n"); - printk("|\tBIF_INTR = %08x\n", bif_intr); - printk("|\tBIF_MHOCR = %08x\n", bif_mhocr); - - printk("|\tBIF_X0SK = %08x\n", bif_x0sk); - printk("|\tBIF_XSK = %08x\n", bif_xsk); - printk("|\tBIF_XSZ = %08x\n", bif_xsz); - printk("|\tBIF_Y0SK = %08x\n", bif_y0sk); - printk("|\tBIF_YSK = %08x\n", bif_ysk); - printk("|\tBIF_YSZ = %08x\n", bif_ysz); - printk("|\tBIF_CX0SK = %08x\n", bif_cx0sk); - printk("|\tBIF_CXSK = %08x\n", bif_cxsk); - printk("|\tBIF_CXSZ = %08x\n", bif_cxsz); - printk("|\tBIF_CY0SK = %08x\n", bif_cy0sk); - printk("|\tBIF_CYSK = %08x\n", bif_cysk); - printk("|\tBIF_CYSZ = %08x\n", bif_cysz); - - printk("|\tBIF_TTL = %08x\n", bif_ttl); - printk("|\tBIF_CTTL = %08x\n", bif_cttl); - printk("|\tBIF_HEADER = %08x\n", bif_header); -} - - -void bif_led_status(void) -{ -#if 1 - static int i = 0; - unsigned char res = 0; - - switch (i) { - case 0: - case 2: - res = 0xff; - break; - case 1: - case 3: - res = 0; - break; - default: - res = 0xFF & (BIF_IN(BIF_SDCSR) >> (((i-4)/4)*8)); - } - i = (i+1) % 20; - - ap_led(res); -#endif -} - -static void get_bif(void) -{ - if (HAVE_BIF()) - return; - - drop_ip_packets = 1; - - DEBUG(("|get_bif started\n")); - - if (dma_state != DMA_IDLE) - ap_dma_wait(DMA_CH2); - -#if SNET_ARBITRATION - /* wait till the host doesn't want the BIF anymore, tossing - any data that arrives */ - while (BIF_IN(FSTT_CLR) & HOST_STATUS_BIT) - if (BIF_IN(BIF_SDCSR) & BIF_SDCSR_RB) - bif_intr_receive(NULL); - waiting_for_bif = 0; -#endif - -#if TOKEN_ARBITRATION - BIF_OUT(FSTT_CLR,HOST_STATUS_BIT); -#endif - - /* request the BIF */ - BIF_OUT(BIF_SDCSR,BIF_SDCSR_BR); - - /* loop waiting for us to get the BIF, tossing any data */ - while (!HAVE_BIF()) - if (BIF_IN(BIF_SDCSR) & BIF_SDCSR_RB) - bif_intr_receive(NULL); - - bif_reset_interrupts(); - if (!interrupt_driven) - bif_mask_interrupts(); - - drop_ip_packets = 0; - -#if TOKEN_ARBITRATION - BIF_OUT(FSTT_SET,HOST_STATUS_BIT); -#endif - - DEBUG(("|get_bif done\n")); -} - - -/* write a message to the front end over the Bnet. This can be in - multiple parts, as long as the first part sets "start" and the last - part sets "end". The bus will be grabbed while this is going on - */ -static void write_bif(char *buf,int size,int start,int end) -{ - unsigned *ibuf; - unsigned avail; - - DEBUG(("|write_bif %d %d %d\n",size,start,end)); - - if (start) { - /* a dma op may be in progress */ - if (dma_state != DMA_IDLE) ap_dma_wait(DMA_CH2); - } - - size = (size+3) >> 2; - ibuf = (unsigned *)buf; - if (end) size--; - - while (size > 4) { - while (!(avail=(BIF_IN(BIF_SDCSR) >> BIF_SDCSR_TB_SHIFT) & 7)) - ; - if (avail & 4) { - BIF_OUT(BIF_DATA,ibuf[0]); - BIF_OUT(BIF_DATA,ibuf[1]); - BIF_OUT(BIF_DATA,ibuf[2]); - BIF_OUT(BIF_DATA,ibuf[3]); - size -= 4; ibuf += 4; - continue; - } - - if (avail & 2) { - BIF_OUT(BIF_DATA,ibuf[0]); - BIF_OUT(BIF_DATA,ibuf[1]); - size -= 2; ibuf += 2; - continue; - } - BIF_OUT(BIF_DATA,ibuf[0]); - ibuf++; size--; - } - - while (size--) { - while (!(BIF_IN(BIF_SDCSR) & BIF_SDCSR_TB)) ; - BIF_OUT(BIF_DATA,ibuf[0]); - ibuf++; - } - - if (end) { - while (!(BIF_IN(BIF_SDCSR) & BIF_SDCSR_TB)) ; - BIF_OUT(BIF_EDATA,*ibuf); - } - - DEBUG(("|write bif done\n")); -} - -#if TOKEN_ARBITRATION -static void forward_token(void) -{ - struct cap_request req; - req.cid = mpp_cid(); - req.type = REQ_BIF_TOKEN; - req.size = sizeof(req); - if (req.cid == cap_init.numcells - 1) - req.header = MAKE_HEADER(HOST_CID); - else - req.header = MAKE_HEADER(req.cid + 1); - - write_bif((char *)&req,sizeof(req),1,1); - have_token = 0; -} -#endif - -static void release_bif(void) -{ - static int dummy[DUMMY_MSG_LEN]; - - waiting_for_bif = 0; - -#if SNET_ARBITRATION - /* mask the attention interrupt */ - attn_mask(); -#endif - - /* maybe we don't have it?? */ - if (!HAVE_BIF()) - return; - - DEBUG(("|release bif started\n")); - - if (dma_state != DMA_IDLE) ap_dma_wait(DMA_CH2); - -#if TOKEN_ARBITRATION - if (have_token) - forward_token(); -#endif - -#if 1 - /* send a dummy message to ensure FIFO flushing - (suggestion from woods to overcome bif release - hardware bug) */ - dummy[0] = 0xEEEE4000; - write_bif((char *)dummy,DUMMY_MSG_LEN,1,1); -#endif - /* wait till the send FIFO is completely empty */ - while (!((BIF_IN(BIF_SDCSR) & BIF_SDCSR_TB) == BIF_SDCSR_TB)) ; - - /* wait another few us */ - udelay(DUMMY_MSG_WAIT); - - /* send release-data */ - BIF_OUT(BIF_DATA,BIF_HEADER_RS); - - /* wait until we don't have the bus */ - while (HAVE_BIF()) ; - - DEBUG(("|release bif done\n")); -} - - -/* wait for a particular request type - throwing away anything else! */ -void ap_wait_request(struct cap_request *req,int type) -{ - drop_ip_packets = 1; - do { - while (!BIF_DATA_WAITING()) - if (HAVE_BIF()) release_bif(); - read_bif((char *)req,sizeof(*req)); - if (req->type != type) { - bif_intr_receive(req); - } - } while (req->type != type); - drop_ip_packets = 0; -} - - -void write_bif_polled(char *buf1,int len1,char *buf2,int len2) -{ - unsigned flags; - save_flags(flags); cli(); - - get_bif(); - write_bif(buf1,len1,1,(buf2&&len2)?0:1); - if (buf2 && len2) - write_bif(buf2,len2,0,1); - release_bif(); - restore_flags(flags); -} - -static void want_bif(void) -{ - unsigned flags; - - save_flags(flags); cli(); - - /* maybe we've already got it */ - if (HAVE_BIF()) { - waiting_for_bif = 0; - restore_flags(flags); - return; - } - -#if SNET_ARBITRATION - if (interrupt_driven) - attn_enable(); - - /* check if the host wants it */ - if (BIF_IN(FSTT_CLR) & HOST_STATUS_BIT) { - /* the host wants it - don't get it yet */ - waiting_for_bif = 1; - } else { - /* the host doesn't want it - just set bus request */ - waiting_for_bif = 0; - BIF_OUT(BIF_SDCSR,BIF_SDCSR_BR); - while (!HAVE_BIF() && !BIF_BUSY()) ; - DEBUG(("|set bif request\n")); - } - restore_flags(flags); - return; -#endif - -#if TOKEN_ARBITRATION - if (net_started && !have_token) { - BIF_OUT(FSTT_CLR,HOST_STATUS_BIT); - restore_flags(flags); - return; - } - BIF_OUT(FSTT_SET,HOST_STATUS_BIT); -#endif - - BIF_OUT(BIF_SDCSR,BIF_SDCSR_BR); - restore_flags(flags); -} - -#define BIF_NOCOPY (1<<0) - -/* a queue of requests that need to be sent over the bif. Needs to be -modified sometime to allow the direct queueing of skb's */ -struct bif_queue { - volatile struct bif_queue *next; - struct cap_request req; - char *data; - int data_size; - int flags; -}; - -static volatile struct bif_queue *bif_queue_top = NULL; -static volatile struct bif_queue *bif_queue_end = NULL; - -static struct sk_buff *skb_out = NULL; -static struct sk_buff *skb_in = NULL; -static char *bif_dma_data = NULL; -static int bif_dma_out_size = 0; - - -/* send waiting elements. Called mainly when we get a bif "bus get" - interrupt to say we now have the bus */ -static void bif_intr_runqueue(void) -{ - unsigned flags; - - /* if I don't have the bus then return */ - if (!HAVE_BIF()) - return; - - if (dma_state != DMA_IDLE) return; - - save_flags(flags); cli(); - - while (bif_queue_top) { - volatile struct bif_queue *q = bif_queue_top; - bif_queue_top = q->next; - - /* printk("|queue run (length=%d)\n",queue_length); */ - queue_length--; - - if (!q->data) { - /* use programmed IO for small requests */ - write_bif((char *)&q->req,sizeof(q->req),1,1); - kfree_s((char *)q,sizeof(*q)); - continue; - } - - if (q->flags & BIF_NOCOPY) { - write_bif((char *)&q->req,sizeof(q->req),1,0); - } - - if (use_dma && q->data_size > DMA_THRESHOLD) { - dma_state = DMA_OUTGOING; - if (q->req.type == REQ_IP) { - skb_out = (struct sk_buff *)q->data; - ap_dma_go(DMA_CH2,(unsigned)skb_out->data, - q->data_size,DMA_DCMD_TD_MD); - } else { - if (!(q->flags & BIF_NOCOPY)) { - bif_dma_data = q->data; - bif_dma_out_size = q->data_size; - } - ap_dma_go(DMA_CH2,(unsigned)q->data, - q->data_size,DMA_DCMD_TD_MD); - } - kfree_s((char *)q,sizeof(*q)); - restore_flags(flags); - return; /* wait for DMA to complete */ - } - - if (q->req.type == REQ_IP) { - struct sk_buff *skb = (struct sk_buff *)q->data; - write_bif(skb->data,q->data_size,1,1); - dev_kfree_skb(skb); - } else { - write_bif(q->data,q->data_size,1,1); - if (!(q->flags & BIF_NOCOPY)) - kfree_s(q->data,q->data_size); - } - kfree_s((char *)q,sizeof(*q)); - } - - /* I don't want the bus now */ - release_bif(); - restore_flags(flags); -} - - -static void queue_attach(struct bif_queue *q) -{ - unsigned flags; - save_flags(flags); cli(); - - /* attach it to the end of the queue */ - if (!bif_queue_top) { - bif_queue_top = q; - } else { - bif_queue_end->next = q; - } - bif_queue_end = q; - - queue_length++; - - /* printk("|queue add (length=%d)\n",queue_length); */ - - /* tell the bus we want access */ - want_bif(); - - restore_flags(flags); -} - - -/* queue an element for sending over the bif. */ -int bif_queue(struct cap_request *req,char *buf,int bufsize) -{ - struct bif_queue *q; - - if (req->header == 0) - req->header = MAKE_HEADER(HOST_CID); - - /* if we aren't running interrupt driven then just send it - immediately */ - if (!interrupt_driven) { - write_bif_polled((char *)req,sizeof(*req),buf,bufsize); - return(0); - } - - /* allocate a queue element */ - q = (struct bif_queue *)kmalloc(sizeof(*q), GFP_ATOMIC); - if (!q) { - /* yikes! */ - return(-ENOMEM); - } - - q->flags = 0; - q->data = NULL; - q->data_size = 0; - - if (buf && bufsize>0) { - q->data_size = bufsize+sizeof(*req); - q->data = (char *)kmalloc(q->data_size,GFP_ATOMIC); - if (!q->data) { - kfree_s(q,sizeof(*q)); - return(-ENOMEM); - } - } - - q->req = *req; - if (buf&&bufsize) { - memcpy(q->data,(char *)req,sizeof(*req)); - memcpy(q->data+sizeof(*req),buf,bufsize); - } - q->next = NULL; - - queue_attach(q); - - return(0); -} - - -/* queue an element for sending over the bif. */ -int bif_queue_nocopy(struct cap_request *req,char *buf,int bufsize) -{ - struct bif_queue *q; - - if (req->header == 0) - req->header = MAKE_HEADER(HOST_CID); - - /* allocate a queue element */ - q = (struct bif_queue *)kmalloc(sizeof(*q), GFP_ATOMIC); - if (!q) { - return(-ENOMEM); - } - - q->data = buf; - q->data_size = bufsize; - q->flags = BIF_NOCOPY; - q->req = *req; - q->next = NULL; - - queue_attach(q); - - return(0); -} - - -/* put an IP packet into the bif queue */ -int bif_send_ip(int cid, struct sk_buff *skb) -{ - struct cap_request *req = (struct cap_request *)skb->data; - struct bif_queue *q; - u_long destip; - - destip = *(u_long *)(skb->data+sizeof(*req)+16); - - if (cid != -1) { - req->header = MAKE_HEADER(cid); - } else if (destip == (cap_init.baseIP | ~cap_init.netmask)) { - req->header = BIF_HEADER_IN | BIF_HEADER_BR; - } else { - req->header = MAKE_HEADER(HOST_CID); - } - - /* allocate a queue element */ - q = (struct bif_queue *)kmalloc(sizeof(*q), GFP_ATOMIC); - if (!q) { - /* yikes! */ - dev_kfree_skb(skb); - return(-ENOMEM); - } - - req->size = ROUND4(skb->len); - req->cid = mpp_cid(); - req->type = REQ_IP; - - q->data = (char *)skb; - q->data_size = req->size; - q->next = NULL; - q->req = *req; - q->flags = 0; - - queue_attach(q); - - return(0); -} - - -/* send an OPENNET request to tell the front end to open the apnet - network interface */ -void start_apnet(void) -{ - struct cap_request req; - req.cid = mpp_cid(); - req.type = REQ_OPENNET; - req.size = sizeof(req); - req.header = MAKE_HEADER(HOST_CID); - - bif_queue(&req,NULL,0); - printk("sent start_apnet request\n"); -} - -/* we have received an IP packet - pass it to the bif network - interface code */ -static void reply_ip(struct cap_request *req) -{ - if (drop_ip_packets || - !(skb_in = dev_alloc_skb(req->size - sizeof(*req)))) { - bif_toss(req->size - sizeof(*req)); - return; - } - - if (use_dma && req->size > DMA_THRESHOLD) { - dma_state = DMA_INCOMING; - ap_dma_go(DMA_CH2, - (unsigned)skb_put(skb_in,req->size - sizeof(*req)), - req->size - sizeof(*req),DMA_DCMD_TD_DM); - } else { - read_bif(skb_put(skb_in,req->size - sizeof(*req)), - req->size - sizeof(*req)); - bif_rx(skb_in); - skb_in = NULL; - } -} - - -/* we have received a bread block - DMA it in */ -static void reply_bread(struct cap_request *req) -{ - extern char *ap_buffer(struct cap_request *creq); - char *buffer; - - buffer = ap_buffer(req); - bread_req = *req; - - if (use_dma) { - dma_state = DMA_INCOMING; - ap_dma_go(DMA_CH2, - (unsigned)buffer,req->size - sizeof(*req), - DMA_DCMD_TD_DM); - } else { - read_bif(buffer,req->size - sizeof(*req)); - ap_complete(&bread_req); - bread_req.type = -1; - } -} - - -static struct debug_key { - struct debug_key *next; - char key; - void (*fn)(void); - char *description; -} *debug_keys = NULL; - - -void show_debug_keys(void) -{ - struct debug_key *r; - for (r=debug_keys;r;r=r->next) - printk("%c: %s\n",r->key,r->description); -} - - -void bif_add_debug_key(char key,void (*fn)(void),char *description) -{ - struct debug_key *r,*r2; - r = (struct debug_key *)kmalloc(sizeof(*r),GFP_ATOMIC); - if (r) { - r->next = NULL; - r->key = key; - r->fn = fn; - r->description = description; - if (!debug_keys) { - debug_keys = r; - } else { - for (r2=debug_keys; - r2->next && r2->key != key;r2=r2->next) ; - - if (r2->key == key) { - r2->fn = fn; - r2->description = description; - kfree_s(r,sizeof(*r)); - } else { - r2->next = r; - } - } - } -} - -/* these are very useful for debugging ! */ -static void reply_putchar(struct cap_request *req) -{ - struct debug_key *r; - - char c = req->data[0]; - - ap_set_user(req->data[1]); - - for (r=debug_keys;r;r=r->next) - if (r->key == c) { - r->fn(); - break; - } - if (!r) - printk("cell %d got character %d [%c]\n",mpp_cid(),(int)c,c); - - ap_set_user(-1); -} - - -/* send a signal to a task by name or pid */ -static void reply_kill(struct cap_request *req) -{ - int sig = req->data[0]; - struct task_struct *p; - int len; - char name[32]; - - len = req->size - sizeof(*req); - if (len == 0) { - int pid = req->data[1]; - p = find_task_by_pid(pid); - - if(p) - send_sig(sig, p, 1); - else - printk("cell %d: no task with pid %d\n",mpp_cid(),pid); - return; - } - - if (len > sizeof(name)-1) { - bif_toss(len); - return; - } - - read_bif(name,len); - name[len] = 0; - - read_lock(&tasklist_lock); - for_each_task(p) - if (strcmp(name,p->comm) == 0) - send_sig(sig,p,1); - read_unlock(&tasklist_lock); -} - - -static struct req_list { - struct req_list *next; - int type; - void (*fn)(struct cap_request *); -} *reg_req_list = NULL; - - -void bif_register_request(int type,void (*fn)(struct cap_request *)) -{ - struct req_list *r,*r2; - r = (struct req_list *)kmalloc(sizeof(*r),GFP_ATOMIC); - if (r) { - r->next = NULL; - r->type = type; - r->fn = fn; - if (!reg_req_list) { - reg_req_list = r; - } else { - for (r2=reg_req_list; - r2->next && r2->type != type;r2=r2->next) ; - - if (r2->type == type) { - r2->fn = fn; - kfree_s(r,sizeof(*r)); - } else { - r2->next = r; - } - } - } -} - - - -/* a request has come in on the bif - process it */ -static void bif_intr_receive(struct cap_request *req1) -{ - struct req_list *r; - extern void ap_open_reply(struct cap_request *creq); - struct cap_request req; - - if (req1) { - req = *req1; - } else { - /* read the main cap request header */ - read_bif((char *)&req,sizeof(req)); - } - - /* service it */ - switch (req.type) - { - case REQ_PUTCHAR: - reply_putchar(&req); - break; - case REQ_KILL: - reply_kill(&req); - break; - case REQ_BREAK: - breakpoint(); - break; - case REQ_IP: - reply_ip(&req); - break; -#if TOKEN_ARBITRATION - case REQ_BIF_TOKEN: - have_token = 1; - want_bif(); - break; -#endif - case REQ_OPENNET: - net_started = 1; - break; - case REQ_BREAD: - reply_bread(&req); - break; - case REQ_BOPEN: - ap_open_reply(&req); - break; - case REQ_BWRITE: - ap_complete(&req); - break; - case REQ_SCHEDULE: - mpp_schedule(&req); - break; - - default: - for (r=reg_req_list;r;r=r->next) - if (r->type == req.type) { - r->fn(&req); - return; - } - printk("Unknown request %d\n",req.type); - break; - } -} - - -static void bif_dma_complete(void) -{ - extern int bif_rx(struct sk_buff *skb); - enum dma_state old_state = dma_state; - unsigned a; - - a = DMA_IN(DMA2_DMST); - - if (a & DMA_DMST_AC) return; - - DMA_OUT(DMA2_DMST,AP_CLR_INTR_REQ< -#include -#include -#include -#include -#include - -#define DMA_MAX_TRANS_SIZE2 (0xfffffc) - -int ap_dma_wait(int ch) -{ - int i = 0; - while (DMA_IN(ch+DMA_DMST) & DMA_DMST_AC) i++; - return i; -} - -/* send some data out a dma channel */ -int ap_dma_go(unsigned long ch,unsigned int p,int size,unsigned long cmd) -{ - int rest; - - p = mmu_v2p(p); - - cmd |= DMA_DCMD_ST | DMA_DCMD_TYP_AUTO; - -#if 0 - if (ap_dma_wait(ch)) { - printk("WARNING: dma started when not complete\n"); - } - - if (cmd == DMA_DCMD_TD_MD && !(BIF_IN(BIF_SDCSR) & BIF_SDCSR_BG)) { - ap_led(0xAA); - printk("attempt to dma without holding the bus\n"); - return -1; - } -#endif - - /* reset the dma system */ - DMA_OUT(ch + DMA_DMST,DMA_DMST_RST); - - if (size <= DMA_MAX_TRANS_SIZE) { - DMA_OUT(ch + DMA_MADDR,(unsigned long)p); - DMA_OUT(ch + DMA_HSKIP,1); - DMA_OUT(ch + DMA_VSKIP,1); - DMA_OUT(ch + DMA_DCMD,cmd | B2W(size)); - return 0; - } - - if (size <= DMA_MAX_TRANS_SIZE2) { - if(size & 0x3) size += 4; - rest = (size & (DMA_TRANS_BLOCK_SIZE - 1)) >> 2; - if (rest) { - DMA_OUT(ch + DMA_HDRP,(unsigned)p); - p += rest << 2; - } - DMA_OUT(ch + DMA_MADDR,(unsigned)p); - DMA_OUT(ch + DMA_HSKIP,size >> (2 + 6)); - DMA_OUT(ch + DMA_VSKIP,1); - DMA_OUT(ch + DMA_DCMD,cmd | (rest << 16) | 64); - return 0; - } - - printk("AP1000 DMA operation too big (%d bytes) - aborting\n",size); - return(-1); -} - diff --git a/arch/sparc/ap1000/hw.c b/arch/sparc/ap1000/hw.c deleted file mode 100644 index aabe15a3b..000000000 --- a/arch/sparc/ap1000/hw.c +++ /dev/null @@ -1,200 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* - * Initialize the AP1000 hardware: BIF, MSC+, MC+, etc. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define APLOG 0 - -/* these make using CellOS code easier */ -int cap_nopt0; -int cap_cid0; -int cap_ncel0; - -unsigned _cid, _ncel, _ncelx, _ncely, _cidx, _cidy; - -/* yuck - needed for sun4c! */ -static unsigned char dummy; -unsigned char *auxio_register = &dummy; - - -extern struct cap_init cap_init; - -static void unexpected_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - ap_panic("** unexpected interrupt %d **\n",irq); -} - -static void ap_other_irqs(void) -{ - request_irq(3, unexpected_irq, SA_INTERRUPT, "unused", 0); - request_irq(5, unexpected_irq, SA_INTERRUPT, "unused", 0); - request_irq(12, unexpected_irq, SA_INTERRUPT, "unused", 0); - request_irq(15, unexpected_irq, SA_INTERRUPT, "unused", 0); -} - -int ap_memory_size(void) -{ - if ((MSC_IN(MSC_SIMMCHK) & MSC_SIMMCHK_MASK) == 0) { - return 16*1024*1024; - } - return 64*1024*1024; -} - -static void show_registers(void) -{ - extern struct pt_regs *bif_pt_regs; - if (bif_pt_regs) - show_regs(bif_pt_regs); - else - printk("unable to show registers\n"); -} - - -static void check_alive(void) -{ - printk("Cell %d is alive\n",mpp_cid()); -} - - - -static void show_task(struct task_struct *t) -{ - printk("cell=%3d uid=%5d pid=%5d utime=%3d stime=%3d etime=%3d name=%s\n", - mpp_cid(), - t->uid, - (int)t->pid, - (int)t->utime, - (int)t->stime, - (jiffies - (int)t->start_time) / 100, - t->comm); -} - -static void show_ptasks(void) -{ - extern struct task_struct *task[]; - struct task_struct *p; - int i; - int count=0; - - read_lock(&tasklist_lock); - for_each_task(p) { - struct task_struct **tp = p->tarray_ptr; - - if(tp >= &task[MPP_TASK_BASE]) { - show_task(p); - count++; - } - } - read_unlock(&tasklist_lock); - - if (count == 0) - printk("no parallel tasks on cell %d\n",mpp_cid()); -} - -static void show_utasks(void) -{ - extern struct task_struct *task[]; - struct task_struct *p; - int i; - int count=0; - - read_lock(&tasklist_lock); - for_each_task(p) { - if(p->uid > 1) { - show_task(task[i]); - count++; - } - } - read_unlock(&tasklist_lock); - - if (count == 0) - printk("no user tasks on cell %d\n",mpp_cid()); -} - - -static void show_otasks(void) -{ - extern struct task_struct *task[]; - struct task_struct *p; - int i; - int count=0; - extern int ap_current_uid; - - read_lock(&tasklist_lock); - for_each_task(p) { - if(p->uid == ap_current_uid) { - show_task(task[i]); - count++; - } - } - read_unlock(&tasklist_lock); - - if (count == 0) - printk("no tasks on cell %d\n",mpp_cid()); -} - - -void do_panic(void) -{ - int *x = 0; - *x = 1; /* uggh */ -} - - -void mpp_hw_init(void) -{ - extern void show_state(void); - extern void breakpoint(void); - extern void ctrl_alt_del(void); - extern void mac_print_state(void); - extern void show_debug_keys(void); - - bif_add_debug_key('c',check_alive,"check if a cell is alive"); - bif_add_debug_key('k',show_debug_keys,"show the kernel debug keys"); - bif_add_debug_key('p',show_registers,"show register info"); - bif_add_debug_key('p',show_registers,"show register info"); - bif_add_debug_key('m',show_mem,"detailed memory stats"); - bif_add_debug_key('s',show_state,"detailed process stats"); - bif_add_debug_key('D',ap_start_debugger,"launch the kernel debugger"); - bif_add_debug_key('i',breakpoint,"send a breakpoint"); - bif_add_debug_key('r',ctrl_alt_del,"run shutdown (doesn't work)"); - bif_add_debug_key('P',show_ptasks,"show running parallel tasks"); - bif_add_debug_key('U',show_utasks,"show all user tasks"); - bif_add_debug_key('O',show_otasks,"show own user tasks"); - bif_add_debug_key('^',do_panic,"panic :-)"); - - - cap_cid0 = BIF_IN(BIF_CIDR1); - cap_ncel0 = cap_init.numcells; - - _cid = cap_cid0; - _ncel = cap_ncel0; - _ncelx = _ncel<8?_ncel:8; - _ncely = ((_ncel-1) / _ncelx) + 1; - _cidx = _cid % _ncelx; - _cidy = _cid / _ncelx; - - ap_bif_init(); - ap_msc_init(); - ap_tnet_init(); - ap_profile_init(); - ap_other_irqs(); - ap_ringbuf_init(); -#if APLOG - ap_log(NULL,-1); -#endif -} diff --git a/arch/sparc/ap1000/irq.c b/arch/sparc/ap1000/irq.c deleted file mode 100644 index d329faf3a..000000000 --- a/arch/sparc/ap1000/irq.c +++ /dev/null @@ -1,64 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void ap_clear_clock_irq(void); -extern void ap_init_timers(void); - -static void ap_enable_irq(unsigned int irq_nr) -{ - /* printk("ENABLE IRQ %d IGNORED\n",irq_nr); */ -} - -static void ap_disable_irq(unsigned int irq_nr) -{ - printk("DISABLE IRQ %d IGNORED\n",irq_nr); -} - -static void ap_clear_profile_irq(void) -{ - MC_OUT(MC_INTR,AP_CLR_INTR_REQ << MC_INTR_ITIM0_SH); -} - -static void ap_load_profile_irq(unsigned limit) -{ - MC_OUT(MC_ITIMER0,limit); -} - -void ap_init_IRQ(void) -{ - enable_irq = ap_enable_irq; - disable_irq = ap_disable_irq; - clear_clock_irq = ap_clear_clock_irq; - clear_profile_irq = ap_clear_profile_irq; - load_profile_irq = ap_load_profile_irq; - init_timers = ap_init_timers; - - sti(); /* the sun4m code does this, so we do too */ -} diff --git a/arch/sparc/ap1000/kgdb.c b/arch/sparc/ap1000/kgdb.c deleted file mode 100644 index fa6c65ecd..000000000 --- a/arch/sparc/ap1000/kgdb.c +++ /dev/null @@ -1,78 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* routines to support remote kgdb to Linux/AP+ cells */ - -#include -#include -#include -#include -#include - -static char out_buf[0x100]; -static int out_buf_pos = 0; - -static char in_buf[0x100]; -static int in_buf_pos = 0; -static int in_buf_count = 0; - -static int hash_pos = -1; - -void ap_dbg_flush(void) -{ - struct cap_request req; - - if (out_buf_pos == 0) return; - - req.cid = mpp_cid(); - req.type = REQ_PUTDEBUGSTRING; - req.size = sizeof(req) + out_buf_pos; - req.header = MAKE_HEADER(HOST_CID); - - write_bif_polled((char *)&req,sizeof(req),(char *)out_buf,out_buf_pos); - - out_buf_pos = 0; - hash_pos = -1; -} - -/* called by the gdb stuff */ -void putDebugChar(char c) -{ - if (c == '#') hash_pos = out_buf_pos; - - out_buf[out_buf_pos++] = c; - if (out_buf_pos == sizeof(out_buf)) { - ap_dbg_flush(); - } -} - -/* used by gdb to get input */ -char getDebugChar(void) -{ - unsigned flags; - struct cap_request req; - - ap_dbg_flush(); - - if (in_buf_count == 0) { - req.cid = mpp_cid(); - req.type = REQ_GETDEBUGCHAR; - req.size = sizeof(req); - req.header = MAKE_HEADER(HOST_CID); - - save_flags(flags); cli(); - write_bif_polled((char *)&req,sizeof(req),NULL,0); - ap_wait_request(&req,REQ_GETDEBUGCHAR); - read_bif(in_buf,req.size - sizeof(req)); - in_buf_pos = 0; - in_buf_count = req.size - sizeof(req); - restore_flags(flags); - } - - in_buf_count--; - return(in_buf[in_buf_pos++]); -} diff --git a/arch/sparc/ap1000/mpp.c b/arch/sparc/ap1000/mpp.c deleted file mode 100644 index 1e6596a07..000000000 --- a/arch/sparc/ap1000/mpp.c +++ /dev/null @@ -1,83 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* - * simple mpp functions for the AP+ - */ - -#include -#include -#include -#include -#include -#include - -extern int cap_cid0; -extern int cap_ncel0; -extern struct cap_init cap_init; - -static volatile int mpp_current_task = 0; -static int gang_factor = DEF_GANG_FACTOR; -static int last_task = 0; - - -void mpp_schedule(struct cap_request *req) -{ - mpp_current_task = req->data[0]; - current->need_resched = 1; - mark_bh(TQUEUE_BH); -} - - -void mpp_notify_schedule(struct task_struct *tsk) -{ - last_task = tsk->taskid; - - msc_switch_check(tsk); - - if (gang_factor == 0) return; - - if (cap_cid0 == cap_init.bootcid && - mpp_current_task != tsk->taskid) { - struct cap_request req; - - mpp_current_task = tsk->taskid; - - req.cid = mpp_cid(); - req.type = REQ_SCHEDULE; - req.size = sizeof(req); - req.header = MAKE_HEADER(-1); - req.data[0] = mpp_current_task; - - bif_queue(&req,NULL,0); - } -} - - -int mpp_weight(struct task_struct *tsk) -{ - extern int block_parallel_tasks; - - if (!MPP_IS_PAR_TASK(tsk->taskid)) return 0; - - if (block_parallel_tasks) return -1000; - - /* XXX task[] fixme */ - if (last_task && last_task != tsk->taskid && task[last_task] && - !msc_switch_ok()) return -1000; - - if (cap_cid0 != cap_init.bootcid && - tsk->taskid != mpp_current_task) { - return -gang_factor; - } - return 0; -} - -void mpp_set_gang_factor(int factor) -{ - gang_factor = factor; -} diff --git a/arch/sparc/ap1000/msc.c b/arch/sparc/ap1000/msc.c deleted file mode 100644 index 088df765c..000000000 --- a/arch/sparc/ap1000/msc.c +++ /dev/null @@ -1,1262 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* - * Routines to control the AP1000+ Message Controller (MSC+) - * and Memory Controller (MC+). - * - */ -#define _APLIB_ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void msc_interrupt_9(int irq, void *dev_id, struct pt_regs *regs); -static void msc_interrupt_11(int irq, void *dev_id, struct pt_regs *regs); -static void msc_set_ringbuf(int context); -static void msc_update_read_ptr(int context,int overflow); -static void fail_write(int context,int intr,unsigned vaddr); -static void fail_read(int context,int intr,unsigned vaddr); -static void msc_switch_from_check(struct task_struct *tsk); -static void msc_status(void); - -#define DEBUG 0 - -/* - * This describes how the 5 queues for outgoing requests - * are mapped into the 256 words of send queue RAM in the MSC+. - */ -#define NSENDQUEUES 5 - -static struct send_queues { - int base; /* must be a multiple of size */ - int size; /* must be 32 or 64 */ -} send_queues[NSENDQUEUES] = { - {0, 64}, /* System put/send requests */ - {192, 32}, /* Remote read/write requests */ - {64, 64}, /* User put/send requests */ - {224, 32}, /* Remote read replies */ - {128, 64}, /* Get replies */ -}; - -#define NR_RBUFS MSC_NR_RBUFS - -static struct { - unsigned rbmbwp; - unsigned rbmmode; - unsigned rbmrp; -} ringbufs[MSC_NR_RBUFS] = { - {MSC_RBMBWP0, MSC_RBMMODE0, MSC_RBMRP0}, - {MSC_RBMBWP1, MSC_RBMMODE1, MSC_RBMRP1}, - {MSC_RBMBWP2, MSC_RBMMODE2, MSC_RBMRP2}, -}; - -#define CTX_MASK 0xfff -#define NULL_CONTEXT CTX_MASK - -#define QOF_ORDER 3 /* 32kB queue overflow buffer */ -#define QOF_SIZE ((1<> 19, MSC_QBMP_BP) \ - + MKFIELD((qof) >> 3, MSC_QBMP_WP) \ - + MKFIELD(((qof) + (size) - 1) >> 13, MSC_QBMP_LIM)) - -#define QBM_UPDATE_WP(wp) \ - MSC_OUT(MSC_QBMPTR, INSFIELD(MSC_IN(MSC_QBMPTR), (unsigned)(wp) >> 3, \ - MSC_QBMP_WP)) - -/* Send queue overflow buffer structure */ -struct qof_elt { - unsigned info; - unsigned data; -}; - -/* Fields in qof_elt.info */ -#define QOF_QUEUE_SH 24 /* queue bits start at bit 24 */ -#define QOF_QUEUE_M 0x1f /* 5 bits wide */ -#define QOF_ENDBIT 1 /* end bit in bit 0 */ - -static struct qof_elt *qof_base=NULL; /* start of overflow buffer */ -static unsigned long qof_phys; /* physical start adrs of overflow buffer */ -static struct qof_elt *qof_rp; /* read pointer for refills */ -static struct qof_elt *qof_new; /* first element we haven't yet looked at */ -static int qof_present[NSENDQUEUES];/* # elts for each q in [qof_rp,qof_new) */ - -/* this is used to flag when the msc is blocked, so we can't send - messages on it without the possability of deadlock */ -int msc_blocked = 0; -int block_parallel_tasks = 0; - -static int qbm_full_counter = 0; - -#define INTR_LIMIT 10000 -static int intr_counter = 0; -static unsigned intr_mask; - -#define DUMMY_RINGBUF_ORDER 5 -#define DUMMY_RINGBUF_SIZE ((1<>5)-1; -unsigned dummy_read_ptr = (DUMMY_RINGBUF_SIZE>>5)-1; - -#define SQ_NEW_MODE(mode) do { \ - MSC_OUT(MSC_SQCTRL, ((MSC_IN(MSC_SQCTRL) & ~MSC_SQC_RMODE) \ - | MSC_SQC_RMODE_ ## mode)); \ - while ((MSC_IN(MSC_SQCTRL) & MSC_SQC_MODE) != MSC_SQC_MODE_ ## mode) \ - /* hang */ ; \ -} while (0) - -/* Repack the queue overflow buffer if >= this many already-used entries */ -#define REPACK_THRESH 64 - - -static void refill_sq(void); -static void repack_qof(void); -static void shuffle_qof(void); -static void async_callback(int, unsigned long, int, int); - - -static void mask_all_interrupts(void) -{ - /* disable all MSC+ interrupts */ - MSC_OUT(MSC_INTR, - (AP_SET_INTR_MASK << MSC_INTR_QBMFUL_SH) | - (AP_SET_INTR_MASK << MSC_INTR_SQFILL_SH) | - (AP_SET_INTR_MASK << MSC_INTR_RBMISS_SH) | - (AP_SET_INTR_MASK << MSC_INTR_RBFULL_SH) | - (AP_SET_INTR_MASK << MSC_INTR_RMASF_SH) | - (AP_SET_INTR_MASK << MSC_INTR_RMASE_SH) | - (AP_SET_INTR_MASK << MSC_INTR_SMASF_SH) | - (AP_SET_INTR_MASK << MSC_INTR_SMASE_SH)); -} - -static inline int valid_task(struct task_struct *tsk) -{ - return(tsk && - !((tsk)->flags & PF_EXITING) && - tsk->mm && - tsk->mm->context != NO_CONTEXT); -} - -static inline unsigned long apmmu_get_raw_ctable_ptr(void) -{ - unsigned int retval; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (APMMU_CTXTBL_PTR), - "i" (ASI_M_MMUREGS)); - return (retval); -} - -static void mc_tlb_map(unsigned phys_page,unsigned vpage,int context) -{ - unsigned long long *tlb4k; - unsigned long long new_entry; - unsigned long *new_entryp = (unsigned long *)&new_entry; - tlb4k = ((unsigned long long *)MC_MMU_TLB4K) + (vpage & 0xFF); - new_entryp[0] = (phys_page&~7) >> 3; - new_entryp[1] = ((phys_page & 7) << 29) | (((vpage>>8)&0xFFF) << 17) | - (context << 5) | 0x13; - tlb4k[0] = new_entry; -#if DEBUG - printk("mc_tlb_map(%x,%x,%x) %x %x at %x\n", - phys_page,vpage,context,new_entryp[0],new_entryp[1],tlb4k); -#endif -} - -static void mc_tlb_unmap(unsigned vpage) -{ - unsigned long long *tlb4k = (unsigned long long *)MC_MMU_TLB4K; - tlb4k = ((unsigned long long *)MC_MMU_TLB4K) + (vpage & 0xFF); - tlb4k[0] = 0; -} - -void mc_tlb_init(void) -{ - unsigned long long *tlb256k, *tlb4k; - int i; - - tlb4k = (unsigned long long *)MC_MMU_TLB4K; - for (i = MC_MMU_TLB4K_SIZE; i > 0; --i) - *tlb4k++ = 0; - tlb256k = (unsigned long long *)MC_MMU_TLB256K; - for (i = MC_MMU_TLB256K_SIZE; i > 0; --i) - *tlb256k++ = 0; -} - -void ap_msc_init(void) -{ - int i, flags, res; - unsigned int qp; - - bif_add_debug_key('M',msc_status,"MSC+ status"); - -#if DEBUG - printk("MSC+ version %x\n", MSC_IN(MSC_VERSION)); - printk("MC+ version %x\n", MC_IN(MC_VERSION)); -#endif - - mc_tlb_init(); - - /* Set the MC's copy of the context table pointer */ - MC_OUT(MC_CTP, apmmu_get_raw_ctable_ptr()); - - /* Initialize the send queue pointers */ - qp = MSC_SQPTR0; - for (i = 0; i < 5; ++i) { - MSC_OUT(qp, ((send_queues[i].size == 64? MSC_SQP_MODE: 0) - + ((send_queues[i].base >> 5) << MSC_SQP_BP_SH))); - qp += (MSC_SQPTR1 - MSC_SQPTR0); - } - - /* Initialize the send queue RAM */ - for (i = 0; i < 256; ++i) - MSC_OUT(MSC_SQRAM + i * 8, -1); - - if (!qof_base) { - qof_base = (struct qof_elt *) __get_free_pages(GFP_ATOMIC, QOF_ORDER); - for (i = MAP_NR(qof_base); i <= MAP_NR(((char*)qof_base)+QOF_SIZE-1);++i) - set_bit(PG_reserved, &mem_map[i].flags); - } - - qof_phys = mmu_v2p((unsigned long) qof_base); - MSC_OUT(MSC_QBMPTR, MAKE_QBMPTR((unsigned long)qof_base, QOF_SIZE)); - qof_rp = qof_base; - qof_new = qof_base; - for (i = 0; i < NSENDQUEUES; ++i) - qof_present[i] = 0; - - SQ_NEW_MODE(NORMAL); /* Set the send queue to normal mode */ - - /* Register interrupt handler for MSC+ */ - save_flags(flags); cli(); - res = request_irq(APMSC_IRQ, msc_interrupt_11, SA_INTERRUPT, - "apmsc", NULL); - if (res != 0) - printk("couldn't register MSC interrupt 11: error=%d\n", res); - res = request_irq(APMAS_IRQ, msc_interrupt_9, SA_INTERRUPT, - "apmas", NULL); - if (res != 0) - printk("couldn't register MSC interrupt 9: error=%d\n", res); - restore_flags(flags); - - MSC_OUT(MSC_MASCTRL, 0); - - /* Enable all MSC+ interrupts (for now) */ - MSC_OUT(MSC_INTR, - (AP_CLR_INTR_MASK << MSC_INTR_QBMFUL_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_SQFILL_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_RBMISS_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_RBFULL_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_RMASF_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_RMASE_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_SMASF_SH) | - (AP_CLR_INTR_MASK << MSC_INTR_SMASE_SH)); - - /* setup invalid contexts */ - for (i=0; i= QOF_GREEN_NELT) { -#if DEBUG - printk("send queue overflow buffer overflow\n"); -#endif - MSC_OUT(MSC_INTR, AP_SET_INTR_MASK << MSC_INTR_QBMFUL_SH); - intr_mask |= (AP_INTR_REQ << MSC_INTR_QBMFUL_SH); - current->need_resched = 1; - block_parallel_tasks = 1; - mark_bh(TQUEUE_BH); - } - ntot = qof_new - qof_rp; /* total # words of qof buf used */ - if (ntot - nvalid >= REPACK_THRESH || ntot >= QOF_GREEN_NELT - || (ntot > nvalid && nvalid >= QOF_GREEN_NELT - REPACK_THRESH)) { - repack_qof(); - if (qof_new - qof_rp != nvalid) { - printk("MSC: qof_present wrong\n"); - } - } else if (nvalid > 0) { - shuffle_qof(); - } - /* N.B. if nvalid == 0, msc_refill_sq has already reset the QBM's WP */ - SQ_NEW_MODE(NORMAL); - - /* dismiss the interrupt */ - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_QBMFUL_SH); -} - - -static void msc_interrupt_11(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned intr; - unsigned long flags; - - save_flags(flags); cli(); - - if (intr_counter++ == INTR_LIMIT) { - mask_all_interrupts(); - printk("too many MSC interrupts\n"); - restore_flags(flags); - return; - } - - intr = MSC_IN(MSC_INTR); - -#if DEBUG - printk("CID(%d) msc_interrupt_11: intr = %x\n", mpp_cid(), intr); -#endif - - if (intr & (AP_INTR_REQ << MSC_INTR_RBMISS_SH)) { - int context; - context = MSC_IN(MSC_RMASREG) >> 20; - - msc_set_ringbuf(context); - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_RBMISS_SH); - } - - if (intr & (AP_INTR_REQ << MSC_INTR_RBFULL_SH)) { - int context = MSC_IN(MSC_RMASREG) >> 20; - msc_update_read_ptr(context,1); - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_RBFULL_SH); - } - - if (intr & (AP_INTR_REQ << MSC_INTR_SQFILL_SH)) { - qbmfill_interrupt(); - } - - if (intr & (AP_INTR_REQ << MSC_INTR_QBMFUL_SH)) { - qbmful_interrupt(); - } - - restore_flags(flags); -} - - -void msc_timer(void) -{ - /* unmask all the interrupts that are supposed to be unmasked */ - intr_counter = 0; -} - -/* assumes NSENDQUEUES == 5 */ -static int log2tbl[32] = { - -1, 0, 1, -1, 2, -1, -1, -1, - 3, -1, -1, -1, -1, -1, -1, -1, - 4, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - -static unsigned long direct_queues[NSENDQUEUES][2] = { - { MSC_SYSTEM_DIRECT, MSC_SYSTEM_DIRECT_END }, - { MSC_REMOTE_DIRECT, MSC_REMOTE_DIRECT_END }, - { MSC_USER_DIRECT, MSC_USER_DIRECT_END }, - { MSC_REMREPLY_DIRECT, MSC_REMREPLY_DIRECT_END }, - { MSC_REPLY_DIRECT, MSC_REPLY_DIRECT_END } -}; - -/* - * Copy entries from the queue overflow buffer back to the send queue. - * This must be called with the send queue controller in THRU mode. - */ -static void refill_sq(void) -{ - int notfull, use_old; - int q, kept_some; - int sqp, sqc; - struct qof_elt *rp, *qof_wp; - int freew[NSENDQUEUES]; /* # free words in each queue */ - - /* give parallel tasks another chance */ - block_parallel_tasks = 0; - - /* get the qbm's write pointer */ - qof_wp = qof_base + (EXTFIELD(MSC_IN(MSC_QBMPTR), MSC_QBMP_WP) - & ((QOF_SIZE - 1) >> 3)); -#if 0 - printk("refill_sq: rp=%p new=%p wp=%p pres=[", - qof_rp, qof_new, qof_wp); - for (q = 0; q < NSENDQUEUES; ++q) - printk("%d ", qof_present[q]); - printk("]\n"); -#endif - - /* work out which send queues and aren't full */ - notfull = 0; - use_old = 0; - for (q = 0; q < NSENDQUEUES; ++q) { - sqp = MSC_IN(MSC_SQPTR0 + q * 8); - freew[q] = (EXTFIELD(sqp, MSC_SQP_RP) - EXTFIELD(sqp, MSC_SQP_WP) - 1) - & ((sqp & MSC_SQP_MODE)? 0x3f: 0x1f); - if (freew[q] > 0) - notfull |= 1 << (q + QOF_QUEUE_SH); - use_old += (freew[q] < qof_present[q])? freew[q]: qof_present[q]; - } - - /* - * If there are useful entries in the old part of the overflow - * queue, process them. - */ - kept_some = 0; - for (rp = qof_rp; rp < qof_new && use_old > 0; ++rp) { - if (rp->info & notfull) { - /* Here's one we can stuff back into the send queue */ - q = log2tbl[EXTFIELD(rp->info, QOF_QUEUE)]; - if (q < 0) { - printk("bad queue bits in qof info (%x) at %p\n", - rp->info, rp); - /* XXX just ignore this entry - should never happen */ - rp->info = 0; - continue; - } - MSC_OUT(direct_queues[q][rp->info & QOF_ENDBIT],rp->data); - if (--freew[q] == 0) - notfull &= ~(1 << (q + QOF_QUEUE_SH)); - --qof_present[q]; - --use_old; - rp->info = 0; - } else if (!kept_some && rp->info != 0) { - qof_rp = rp; - kept_some = 1; - } - } - - /* Trim off any further already-used items. */ - if (!kept_some) { - for (; rp < qof_new; ++rp) { - if (rp->info) { - qof_rp = rp; - kept_some = 1; - break; - } - } - } - - /* - * Now process everything that's arrived since we last updated qof_new. - */ - for (rp = qof_new; rp < qof_wp; ++rp) { - if (rp->info == 0) - continue; - q = log2tbl[EXTFIELD(rp->info, QOF_QUEUE)]; - if (q < 0) { - printk("bad queue bits in qof info (%x) at %p\n", rp->info, rp); - /* XXX just ignore this entry - should never happen */ - rp->info = 0; - continue; - } - if (rp->info & notfull) { - /* Another one to stuff back into the send queue. */ - MSC_OUT(direct_queues[q][rp->info & QOF_ENDBIT],rp->data); - if (--freew[q] == 0) - notfull &= ~(1 << (q + QOF_QUEUE_SH)); - rp->info = 0; - } else { - ++qof_present[q]; - if (!kept_some) { - qof_rp = rp; - kept_some = 1; - } - } - } - - /* Update state and the MSC queue-spill flags. */ - if (!kept_some) { - /* queue is empty; avoid unnecessary overflow interrupt later */ - qof_rp = qof_new = qof_base; - QBM_UPDATE_WP(mmu_v2p((unsigned long)qof_base)); - } else { - qof_new = qof_wp; - } - - sqc = MSC_IN(MSC_SQCTRL); - for (q = 0; q < NSENDQUEUES; ++q) - if (qof_present[q] == 0 && freew[q] > 0) - sqc &= ~(1 << (q + MSC_SQC_SPLF_SH)); - MSC_OUT(MSC_SQCTRL, sqc); -} - -/* - * Copy the valid entries from their current position - * in the queue overflow buffer to the beginning. - * This must be called with the send queue controller in THRU or BLOCKING mode. - */ -static void repack_qof(void) -{ - struct qof_elt *rp, *wp; - - wp = qof_base; - for (rp = qof_rp; rp < qof_new; ++rp) { - if (rp->info) { - if (rp > wp) - *wp = *rp; - ++wp; - } - } - qof_rp = qof_base; - qof_new = wp; - QBM_UPDATE_WP(wp); -} - -/* - * Copy all entries from their current position - * in the queue overflow buffer to the beginning. - * This must be called with the send queue controller in THRU or BLOCKING mode. - */ -static void shuffle_qof(void) -{ - int n; - - n = qof_new - qof_rp; - memmove(qof_base, qof_rp, n * sizeof(struct qof_elt)); - qof_rp = qof_base; - qof_new = qof_base + n; - QBM_UPDATE_WP(qof_new); -} - -static inline void handle_signal(int context,unsigned vaddr) -{ - int signum = (vaddr - MSC_REM_SIGNAL) >> PAGE_SHIFT; - int taskid = MPP_CTX_TO_TASK(context); - if (MPP_IS_PAR_TASK(taskid) && valid_task(task[taskid])) { - send_sig(signum,task[taskid],1); -#if DEBUG - printk("CID(%d) sent signal %d to task %d\n",mpp_cid(),signum,taskid); -#endif - } -} - - -/* - * fail a msc write operation. We use Pauls dirty tlb trick to avoide - * the msc hardware bugs - */ -static void fail_write(int context,int intr,unsigned vaddr) -{ - int tsk = MPP_CTX_TO_TASK(context); - int vpage = vaddr >> 12; -#if DEBUG - printk("fail write tsk=%d intr=%x vaddr=%x RMASREG=%x errproc=%x\n", - tsk,intr,vaddr,MSC_IN(MSC_RMASREG),MSC_IN(MSC_RHDERRPROC)); -#endif - - mc_tlb_map(0x800000 | (mmu_v2p((unsigned)dummy_ringbuf.ringbuf)>>12), - vpage,context); - MSC_OUT(MSC_MASCTRL, MSC_IN(MSC_MASCTRL) & ~MSC_MASC_RFEXIT); - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << intr); - - mc_tlb_unmap(vpage); - - if (MPP_IS_PAR_CTX(context) && valid_task(task[tsk])) { - if (vaddr - MSC_REM_SIGNAL < _NSIG*PAGE_SIZE) { - handle_signal(context,vaddr); - } else { - task[tsk]->thread.sig_address = vaddr; - task[tsk]->thread.sig_desc = SUBSIG_NOMAPPING; - send_sig(SIGSEGV, task[tsk], 1); - } - } -} - -/* - * fail a msc read operation using the tlb trick */ -static void fail_read(int context,int intr,unsigned vaddr) -{ - int tsk = MPP_CTX_TO_TASK(context); -#if DEBUG - printk("fail read tsk=%d intr=%x\n",tsk,intr); -#endif - - mc_tlb_map(0x800000 | (mmu_v2p((unsigned)dummy_ringbuf.ringbuf)>>12), - vaddr>>12,context); - MSC_OUT(MSC_MASCTRL, MSC_IN(MSC_MASCTRL) & ~MSC_MASC_SFEXIT); - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << intr); - - mc_tlb_unmap(vaddr>>12); - - if (MPP_IS_PAR_CTX(context) && valid_task(task[tsk])) { - if (vaddr - MSC_REM_SIGNAL < _NSIG*PAGE_SIZE) { - handle_signal(context,vaddr); - } else { - task[tsk]->thread.sig_address = vaddr; - task[tsk]->thread.sig_desc = SUBSIG_NOMAPPING; - send_sig(SIGSEGV, task[tsk], 1); - } - } -} - -static void async_callback(int tsk,unsigned long vaddr,int write,int ret) -{ - unsigned flags; - save_flags(flags); cli(); - - msc_blocked--; - if (write) { - intr_mask &= ~(AP_INTR_REQ << MSC_INTR_RMASF_SH); - if (ret) { - fail_write(MPP_TASK_TO_CTX(tsk),MSC_INTR_RMASF_SH,vaddr); - MSC_OUT(MSC_INTR, AP_CLR_INTR_MASK << MSC_INTR_RMASF_SH); - restore_flags(flags); - return; - } - MSC_OUT(MSC_MASCTRL, MSC_IN(MSC_MASCTRL) & ~MSC_MASC_RFEXIT); - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_RMASF_SH); - MSC_OUT(MSC_INTR, AP_CLR_INTR_MASK << MSC_INTR_RMASF_SH); - } else { - intr_mask &= ~(AP_INTR_REQ << MSC_INTR_SMASF_SH); - if (ret) { - fail_read(MPP_TASK_TO_CTX(tsk),MSC_INTR_SMASF_SH,vaddr); - MSC_OUT(MSC_INTR, AP_CLR_INTR_MASK << MSC_INTR_SMASF_SH); - restore_flags(flags); - return; - } - MSC_OUT(MSC_MASCTRL, MSC_IN(MSC_MASCTRL) & ~MSC_MASC_SFEXIT); - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_SMASF_SH); - MSC_OUT(MSC_INTR, AP_CLR_INTR_MASK << MSC_INTR_SMASF_SH); - } - restore_flags(flags); -} - - - -static inline void msc_write_fault(void) -{ - unsigned context = MSC_IN(MSC_RMASREG) >> 20; - unsigned vaddr = MSC_IN(MSC_RMASTWP)<<12; - - if (context == SYSTEM_CONTEXT) { - fail_write(context,MSC_INTR_RMASF_SH,vaddr); - show_mapping_ctx(0,context,vaddr); - printk("ERROR: system write fault at %x\n",vaddr); - return; - } - - if (vaddr - MSC_REM_SIGNAL < _NSIG*PAGE_SIZE) { - fail_write(context,MSC_INTR_RMASF_SH,vaddr); - return; - } - - if (MPP_IS_PAR_CTX(context)) { - int tsk = MPP_CTX_TO_TASK(context); - if (valid_task(task[tsk]) && task[tsk]->ringbuf) { - MSC_OUT(MSC_INTR, - AP_SET_INTR_MASK << MSC_INTR_RMASF_SH); - intr_mask |= (AP_INTR_REQ << MSC_INTR_RMASF_SH); -#if DEBUG - show_mapping_ctx(0,context,vaddr); -#endif - msc_blocked++; - async_fault(vaddr,1,tsk,async_callback); - return; - } - } - -#if DEBUG - printk("CID(%d) mas write fault context=%x vaddr=%x\n", - mpp_cid(),context,vaddr); -#endif - - fail_write(context,MSC_INTR_RMASF_SH,vaddr); -} - - -static inline void msc_read_fault(void) -{ - unsigned context = MSC_IN(MSC_SMASREG) >> 20; - unsigned vaddr = MSC_IN(MSC_SMASTWP)<<12; - - if (context == SYSTEM_CONTEXT) { - fail_read(context,MSC_INTR_SMASF_SH,vaddr); - show_mapping_ctx(0,context,vaddr); - printk("ERROR: system read fault at %x\n",vaddr); - return; - } - - if (MPP_IS_PAR_CTX(context)) { - int tsk = MPP_CTX_TO_TASK(context); - - if (vaddr - MSC_REM_SIGNAL < _NSIG*PAGE_SIZE) { - fail_read(context,MSC_INTR_SMASF_SH,vaddr); - return; - } - - if (valid_task(task[tsk]) && task[tsk]->ringbuf) { - MSC_OUT(MSC_INTR, AP_SET_INTR_MASK << MSC_INTR_SMASF_SH); - intr_mask |= (AP_INTR_REQ << MSC_INTR_SMASF_SH); - msc_blocked++; - async_fault(vaddr,0,tsk,async_callback); - return; - } - } - -#if DEBUG - printk("CID(%d) mas read fault context=%x vaddr=%x\n", - mpp_cid(),context,vaddr); -#endif - - fail_read(context,MSC_INTR_SMASF_SH,vaddr); -} - - - -static void msc_interrupt_9(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - unsigned intr, cnt, r; - - save_flags(flags); cli(); - - if (intr_counter++ == INTR_LIMIT) { - mask_all_interrupts(); - printk("too many MSC interrupts\n"); - restore_flags(flags); - return; - } - - intr = MSC_IN(MSC_INTR) & ~intr_mask; - -#if DEBUG - printk("CID(%d) msc_interrupt_9: intr = %x\n", mpp_cid(), intr); -#endif - - if (intr & (AP_INTR_REQ << MSC_INTR_RMASF_SH)) { - msc_write_fault(); - } - - if (intr & (AP_INTR_REQ << MSC_INTR_SMASF_SH)) { - msc_read_fault(); - } - - if (intr & (AP_INTR_REQ << MSC_INTR_RMASE_SH)) { - printk("recv mas error interrupt (write)\n"); - printk("masctrl = %x\n", MSC_IN(MSC_MASCTRL)); - printk("rmasadr = %x %x\n", MSC_IN(MSC_RMASADR), - MSC_IN(MSC_RMASADR + 4)); - printk("rmastwp = %x\n", MSC_IN(MSC_RMASTWP)); - printk("rmasreg = %x\n", MSC_IN(MSC_RMASREG)); - r = MSC_IN(MSC_RMASREG); - if ((r & MSC_MASR_AVIO) || (r & MSC_MASR_CMD) != MSC_MASR_CMD_XFER) - /* throw away the rest of the incoming data */ - MSC_OUT(MSC_RHDERRPROC, 0); - /* clear the interrupt */ - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_RMASE_SH); - } - - if (intr & (AP_INTR_REQ << MSC_INTR_SMASE_SH)) { - printk("send mas error interrupt (read)\n"); - printk("masctrl = %x\n", MSC_IN(MSC_MASCTRL)); - printk("smasadr = %x %x\n", MSC_IN(MSC_SMASADR), - MSC_IN(MSC_SMASADR + 4)); - printk("smascnt = %x\n", MSC_IN(MSC_SMASCNT)); - printk("smastwp = %x\n", MSC_IN(MSC_SMASTWP)); - printk("smasreg = %x\n", MSC_IN(MSC_SMASREG)); - /* supply dummy data */ - cnt = MSC_IN(MSC_SMASCNT); - switch (MSC_IN(MSC_SMASREG) & MSC_MASR_CMD) { - case MSC_MASR_CMD_XFER: - MSC_OUT(MSC_HDGERRPROC, (EXTFIELD(cnt, MSC_SMCT_MCNT) - + EXTFIELD(cnt, MSC_SMCT_ICNT))); - break; - /* case remote read: */ - case MSC_MASR_CMD_FOP: - case MSC_MASR_CMD_CSI: - MSC_OUT(MSC_HDGERRPROC, 1); - break; - } - /* clear interrupt */ - MSC_OUT(MSC_INTR, AP_CLR_INTR_REQ << MSC_INTR_SMASF_SH); - } - - restore_flags(flags); -} - -/* - * remove access to a tasks ring buffer - */ -void msc_unset_ringbuf(int i) -{ - int ctx = MSC_IN(ringbufs[i].rbmmode) & CTX_MASK; - int tsk = MPP_CTX_TO_TASK(ctx); - struct ringbuf_struct *rbuf; - -#if DEBUG - printk("msc_unset_ringbuf(%d) %x\n",i,ctx); -#endif - - MSC_OUT(ringbufs[i].rbmmode,NULL_CONTEXT); - if (ctx == SYSTEM_CONTEXT) { - rbuf = &system_ringbuf; - } else if (ctx != NULL_CONTEXT && MPP_IS_PAR_CTX(ctx) && - valid_task(task[tsk]) && task[tsk]->ringbuf) { - rbuf = task[tsk]->ringbuf; - } else if (ctx != NULL_CONTEXT && MPP_IS_PAR_CTX(ctx) && - valid_task(task[tsk]) && task[tsk]->aplib) { - rbuf = &system_ringbuf; - } else { - rbuf = &dummy_ringbuf; - } - - rbuf->write_ptr = MSC_IN(ringbufs[i].rbmbwp); -} - -static void msc_update_read_ptr(int context,int overflow) -{ - int i; - unsigned new_read_ptr; - - for (i=0;iringbuf) { - struct task_struct *tsk = task[MPP_CTX_TO_TASK(context)]; - struct _kernel_cap_shared *_kernel; - unsigned soft_read_ptr; - unsigned octx; - - octx = apmmu_get_context(); - if (octx != context) - apmmu_set_context(context); - _kernel = (struct _kernel_cap_shared *)(RBUF_VBASE + RBUF_SHARED_PAGE_OFF); - soft_read_ptr = _kernel->rbuf_read_ptr; - if (octx != context) - apmmu_set_context(octx); - - if (overflow && MSC_IN(ringbufs[i].rbmrp) == soft_read_ptr) { - /* send them a SIGLOST and wipe their ring buffer */ - printk("ring buffer overflow for %s ctx=%x\n", - tsk->comm,context); - send_sig(SIGLOST,tsk,1); - soft_read_ptr--; - } - new_read_ptr = soft_read_ptr; - } else if (MPP_IS_PAR_CTX(context) && - valid_task(task[MPP_CTX_TO_TASK(context)]) && - task[MPP_CTX_TO_TASK(context)]->aplib) { - tnet_check_completion(); - if (overflow && MSC_IN(ringbufs[i].rbmrp) == system_read_ptr) - printk("system ringbuffer overflow\n"); - new_read_ptr = system_read_ptr; - } else { - dummy_read_ptr = MSC_IN(ringbufs[i].rbmrp) - 1; - new_read_ptr = dummy_read_ptr - 1; -#if DEBUG - if (overflow) - printk("reset dummy ring buffer for context %x\n", - context); -#endif - } - - - MSC_OUT(ringbufs[i].rbmrp,new_read_ptr); -} - -/* - * give a task one of the system ring buffers - * this is called on a context miss interrupt, so we can assume that - * the tasks context is not currently set in one of the ringbufs - */ -static void msc_set_ringbuf(int context) -{ - int i; - int ctx; - int mode; - unsigned write_ptr; - static unsigned next_ctx = 0; - struct ringbuf_struct *rbuf; - - if (context == SYSTEM_CONTEXT) { - rbuf = &system_ringbuf; - } else if (MPP_IS_PAR_CTX(context) && - valid_task(task[MPP_CTX_TO_TASK(context)]) && - task[MPP_CTX_TO_TASK(context)]->ringbuf) { - struct task_struct *tsk = task[MPP_CTX_TO_TASK(context)]; - rbuf = tsk->ringbuf; - } else if (MPP_IS_PAR_CTX(context) && - valid_task(task[MPP_CTX_TO_TASK(context)]) && - task[MPP_CTX_TO_TASK(context)]->aplib) { - rbuf = &system_ringbuf; - } else { - /* use the dummy ring buffer */ - rbuf = &dummy_ringbuf; - } - - for (i=0;iwrite_ptr; - mode = (rbuf->order - 5) >> 1; - - MSC_OUT(ringbufs[i].rbmmode,context | (mode << 12)); - MSC_OUT(ringbufs[i].rbmbwp,write_ptr); - - if (rbuf == &system_ringbuf) { - MSC_OUT(ringbufs[i].rbmrp,system_read_ptr); - } else { - msc_update_read_ptr(context,0); - } - -#if DEBUG - printk("CID(%d) mapped ringbuf for context %d in slot %d\n", - mpp_cid(),context,i); -#endif -} - - -/* - * this is called when a task exits -*/ -void exit_msc(struct task_struct *tsk) -{ - int i; - - if (!MPP_IS_PAR_TASK(tsk->taskid)) - return; - -#if DEBUG - printk("exit_msc(%d) ctx=%d\n",tsk->taskid,tsk->mm->context); -#endif - - for (i=0;itaskid)) - msc_unset_ringbuf(i); - } - msc_switch_from_check(tsk); - - /* stop it receiving new-style messages */ - tsk->aplib = NULL; - - exit_ringbuf(tsk); -} - - -static void msc_sq_pause(void) -{ - MSC_OUT(MSC_SQCTRL,MSC_IN(MSC_SQCTRL) | MSC_SQC_PAUSE); - while (!(MSC_IN(MSC_SQCTRL) & MSC_SQC_STABLE)) /* wait for stable bit */ ; -} - -static void msc_sq_resume(void) -{ - MSC_OUT(MSC_SQCTRL,MSC_IN(MSC_SQCTRL) & ~MSC_SQC_PAUSE); -} - -static void msc_switch_from_check(struct task_struct *tsk) -{ - int user_count; - unsigned flags; - struct ringbuf_struct *rbuf = NULL; - int octx, ctx; - - if (valid_task(tsk) && tsk->ringbuf) - rbuf = tsk->ringbuf; - - /* it doesn't seem obvious why this field should contain count+1, - but it does */ - user_count = EXTFIELD(MSC_IN(MSC_QWORDCNT),MSC_QWDC_USRCNT) - 1; - - /* check if the user queue count is != 0 */ - if (user_count == 0) return; - - if (!rbuf) - printk("switching from dead task\n"); - -#if 1 - printk("saving %d words MSC_QWORDCNT=%x\n", - user_count,MSC_IN(MSC_QWORDCNT)); -#endif - - /* bugger - we have to do some messy work */ - save_flags(flags); cli(); - - ctx = MPP_TASK_TO_CTX(tsk->taskid); - octx = apmmu_get_context(); - if (octx != ctx) - apmmu_set_context(ctx); - - msc_sq_pause(); - - /* remember the expected length of the command - usually (always?) 8 */ - if (rbuf) - rbuf->frag_len = EXTFIELD(MSC_IN(MSC_QWORDCNT),MSC_QWDC_USRLEN); - - /* pull words from the overflow first */ - if (MSC_IN(MSC_SQCTRL) & MSC_SQC_USERF) { - /* we have overflowed */ - struct qof_elt *qof_wp = qof_base + - (EXTFIELD(MSC_IN(MSC_QBMPTR), MSC_QBMP_WP) & ((QOF_SIZE - 1) >> 3)); - while (qof_wp != qof_rp && user_count) { - qof_wp--; - /* only grab elements in the user queue */ - if (qof_wp->info && log2tbl[EXTFIELD(qof_wp->info, QOF_QUEUE)] == 2) { - if (qof_wp->info & 1) { - printk("MSC: end bit set - yikes!\n"); - } - qof_wp->info = 0; - if (rbuf) { - rbuf->sq_fragment[--user_count] = qof_wp->data; - rbuf->frag_count++; - } - if (qof_wp < qof_new) - qof_present[2]--; - } - } -#if DEBUG - if (rbuf) - printk("pulled %d elements from overflow (%d left)\n", - rbuf->frag_count,user_count); -#endif - } - - /* then pull words direct from the msc ram */ - if (user_count) { - int wp = EXTFIELD(MSC_IN(MSC_SQPTR2),MSC_SQP_WP); - int i; - wp -= user_count; - if (wp < 0) wp += send_queues[2].size; - - for (i=0;isq_fragment[i + rbuf->frag_count] = - MSC_IN(MSC_SQRAM + (send_queues[2].base + wp2)*8); - } - - if (rbuf) - rbuf->frag_count += user_count; - - MSC_OUT(MSC_SQPTR2,INSFIELD(MSC_IN(MSC_SQPTR2),wp,MSC_SQP_WP)); -#if DEBUG - printk("saved %d words from msc ram\n",rbuf->frag_count); -#endif - } - - /* reset the user count to 1 */ - MSC_OUT(MSC_QWORDCNT,INSFIELD(MSC_IN(MSC_QWORDCNT),1,MSC_QWDC_USRCNT)); - - msc_sq_resume(); - - if (octx != ctx) - apmmu_set_context(octx); - - restore_flags(flags); -} - -static void msc_switch_to_check(struct task_struct *tsk) -{ - int i; - unsigned flags; - int octx, ctx; - - if (!valid_task(tsk) || !tsk->ringbuf) - return; - - save_flags(flags); cli(); - - - ctx = MPP_TASK_TO_CTX(tsk->taskid); - octx = apmmu_get_context(); - if (octx != ctx) - apmmu_set_context(ctx); - - /* if the task we are switching to has no saved words then - we're finished */ - if (tsk->ringbuf->frag_count == 0) { - if (octx != ctx) - apmmu_set_context(octx); - restore_flags(flags); - return; - } - - -#if 1 - printk("frag fill MSC_QWORDCNT=%x frag_count=%d\n", - MSC_IN(MSC_QWORDCNT),tsk->ringbuf->frag_count); -#endif - - /* reset the user length */ - MSC_OUT(MSC_QWORDCNT,INSFIELD(MSC_IN(MSC_QWORDCNT), - tsk->ringbuf->frag_len, - MSC_QWDC_USRLEN)); - - /* push the words into the direct queue */ - for (i=0;iringbuf->frag_count;i++) - MSC_OUT(MSC_USER_DIRECT,tsk->ringbuf->sq_fragment[i]); - - /* reset the user count */ - MSC_OUT(MSC_QWORDCNT,INSFIELD(MSC_IN(MSC_QWORDCNT), - 1+tsk->ringbuf->frag_count, - MSC_QWDC_USRCNT)); - -#if DEBUG - printk("frag fill done MSC_QWORDCNT=%x\n", - MSC_IN(MSC_QWORDCNT)); -#endif - - tsk->ringbuf->frag_count = 0; - tsk->ringbuf->frag_len = 0; - if (octx != ctx) - apmmu_set_context(octx); - restore_flags(flags); -} - - - -void msc_switch_check(struct task_struct *tsk) -{ - static int last_task = 0; - - if (last_task == tsk->taskid) return; - - if (MPP_IS_PAR_TASK(last_task)) - msc_switch_from_check(task[last_task]); - - msc_switch_to_check(tsk); - - last_task = tsk->taskid; -} - -/* we want to try to avoid task switching while there are partial commands - in the send queues */ -int msc_switch_ok(void) -{ - if ((EXTFIELD(MSC_IN(MSC_QWORDCNT),MSC_QWDC_USRCNT) - 1)) - return 0; - - return 1; -} - -/* - * print out the state of the msc -*/ -static void msc_status(void) -{ - int i; - - printk("MSC_SQCTRL=%x\n",MSC_IN(MSC_SQCTRL)); - - for (i=0;i<5;i++) - printk("MSC_SQPTR%d=%x\n",i,MSC_IN(MSC_SQPTR0 + 8*i)); - printk("MSC_OPTADR=%x\n",MSC_IN(MSC_OPTADR)); - printk("MSC_MASCTRL=%x\n", MSC_IN(MSC_MASCTRL)); - printk("MSC_SMASADR=%x_%x\n", MSC_IN(MSC_SMASADR),MSC_IN(MSC_SMASADR + 4)); - printk("MSC_RMASADR=%x_%x\n", MSC_IN(MSC_RMASADR),MSC_IN(MSC_RMASADR + 4)); - printk("MSC_PID=%x\n",MSC_IN(MSC_PID)); - - printk("MSC_QWORDCNT=%x\n",MSC_IN(MSC_QWORDCNT)); - - printk("MSC_INTR=%x\n",MSC_IN(MSC_INTR)); - printk("MSC_CIDRANGE=%x\n",MSC_IN(MSC_CIDRANGE)); - printk("MSC_QBMPTR=%x\n",MSC_IN(MSC_QBMPTR)); - printk("MSC_SMASTWP=%x\n", MSC_IN(MSC_SMASTWP)); - printk("MSC_RMASTWP=%x\n", MSC_IN(MSC_RMASTWP)); - printk("MSC_SMASREG=%x\n", MSC_IN(MSC_SMASREG)); - printk("MSC_RMASREG=%x\n", MSC_IN(MSC_RMASREG)); - printk("MSC_SMASCNT=%x\n", MSC_IN(MSC_SMASCNT)); - printk("MSC_IRL=%x\n", MSC_IN(MSC_IRL)); - printk("MSC_SIMMCHK=%x\n", MSC_IN(MSC_SIMMCHK)); - - for (i=0;i<3;i++) { - printk("RBMBWP%d=%x\n",i,MSC_IN(ringbufs[i].rbmbwp)); - printk("RBMMODE%d=%x\n",i,MSC_IN(ringbufs[i].rbmmode)); - printk("RBMRP%d=%x\n",i,MSC_IN(ringbufs[i].rbmrp)); - } - - printk("DMA_GEN=%x\n",MSC_IN(DMA_GEN)); - - printk("qbm_full_counter=%d\n",qbm_full_counter); -} diff --git a/arch/sparc/ap1000/sync.c b/arch/sparc/ap1000/sync.c deleted file mode 100644 index 2f8a7cd34..000000000 --- a/arch/sparc/ap1000/sync.c +++ /dev/null @@ -1,55 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* sync functions using the Tnet */ - -#include -#include -#include -#include - -extern int cap_cid0; -extern unsigned _ncel, _ncelx, _ncely, _cid; - -static volatile int sync_flags[MPP_NUM_TASKS]; - - -int ap_sync(int numcells, int *phys_map) -{ - int basecell; - int i,err; - int tsk = current->taskid; - - if (numcells < 2) return 0; - - if (!MPP_IS_PAR_TASK(tsk)) { - printk("nonparallel task %d called ap_sync\n",tsk); - return 0; - } - tsk -= MPP_TASK_BASE; - - basecell = phys_map[0]; - if (cap_cid0 == basecell) { - if ((err=wait_on_int(&sync_flags[tsk],numcells-1,5))) - return err; - sync_flags[tsk] = 0; - if (numcells == _ncel) { - ap_bput(0,0,0,&sync_flags[tsk],0); - } else { - for (i=1;i -#include -#include -#include -#include -#include -#include -#include - -#define INIT_TIM1 (781250/HZ) -#define INIT_TIM0 (781250/(10*HZ)) - -static unsigned long last_freerun; - -unsigned ap_freerun(void) -{ - return *((volatile unsigned long *)(MC_FREERUN + 4)); -} - -void ap_clear_clock_irq(void) -{ - MC_OUT(MC_INTR, AP_CLR_INTR_REQ << MC_INTR_ITIM1_SH); - last_freerun = *((unsigned long *)(MC_FREERUN + 4)); - tnet_check_completion(); -#if 1 - if ((((unsigned)jiffies) % (HZ/4)) == 0) { - msc_timer(); - ap_xor_led(1); - bif_timer(); - ap_dbg_flush(); -#if 0 - bif_led_status(); -#endif - } -#endif -} - - -void ap_gettimeofday(struct timeval *xt) -{ - unsigned long d; - unsigned v; - unsigned long new_freerun; - - /* this is in 80ns units - we only use the low 32 bits - as 5mins is plenty for this stuff */ - d = new_freerun = *((unsigned long *)(MC_FREERUN + 4)); - - if (d < last_freerun) { - /* wraparound */ - d += ((~0) - last_freerun); - } else { - d -= last_freerun; - } - - /* convert to microseconds */ - v = ((d&0xffffff)*10)/125; - - /* only want microseconds/HZ */ - v = v%(1000000/HZ); - - xt->tv_usec += v; - - last_freerun = new_freerun; -} - -static void profile_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - if (prof_buffer && current->pid) { - extern int _stext; - unsigned long ip = instruction_pointer(regs); - ip -= (unsigned long) &_stext; - ip >>= prof_shift; - if (ip < prof_len) - prof_buffer[ip]++; - } - MC_OUT(MC_INTR,AP_CLR_INTR_REQ << MC_INTR_ITIM0_SH); -} - -void ap_profile_init(void) -{ - if (prof_shift) { - printk("Initialising profiling with prof_shift=%d\n",(int)prof_shift); - MC_OUT(MC_INTR,AP_CLR_INTR_REQ << MC_INTR_ITIM0_SH); - MC_OUT(MC_INTR,AP_CLR_INTR_MASK << MC_INTR_ITIM0_SH); - } -} - -void ap_init_timers(void) -{ - extern void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs); - unsigned flags; - - printk("Initialising ap1000 timer\n"); - - save_flags(flags); cli(); - - request_irq(APTIM1_IRQ, - timer_interrupt, - (SA_INTERRUPT | SA_STATIC_ALLOC), - "timer", NULL); - - request_irq(APTIM0_IRQ, - profile_interrupt, - (SA_INTERRUPT | SA_STATIC_ALLOC), - "profile", NULL); - - ap_clear_clock_irq(); - - MC_OUT(MC_ITIMER0,INIT_TIM0); - MC_OUT(MC_ITIMER1,INIT_TIM1); - MC_OUT(MC_INTR,AP_CLR_INTR_REQ << MC_INTR_ITIM1_SH); - MC_OUT(MC_INTR,AP_CLR_INTR_MASK << MC_INTR_ITIM1_SH); - MC_OUT(MC_INTR,AP_SET_INTR_MASK << MC_INTR_ITIM0_SH); - restore_flags(flags); -} diff --git a/arch/sparc/ap1000/tnet.c b/arch/sparc/ap1000/tnet.c deleted file mode 100644 index 777f169f8..000000000 --- a/arch/sparc/ap1000/tnet.c +++ /dev/null @@ -1,708 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* routines to control the AP1000 Tnet interface */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -/* message types for system messages */ -#define TNET_IP 0 -#define TNET_IP_SMALL 1 -#define TNET_RPC 2 - -static struct { - int errors; - int alloc_errors; - int bytes_received; - int bytes_sent; - int packets_received; - int packets_sent; - int small_packets_received; - int small_packets_sent; -} tnet_stats; - -extern int cap_cid0; -extern int cap_ncel0; -static u_long xy_global_head; - -extern unsigned _ncel, _ncelx, _ncely, _cid, _cidx, _cidy; - -extern struct ringbuf_struct system_ringbuf; -extern u_long system_read_ptr; - -u_long system_recv_flag = 0; -static u_long system_recv_count = 0; - -int *tnet_rel_cid_table; - -static int dummy=1; - -#define TNET_IP_THRESHOLD 100 - -void tnet_check_completion(void); -static void reschedule(void); -static u_long tnet_add_completion(void (*fn)(int a1,...), - int a1,int a2); -static void tnet_info(void); - -static struct { - int shift; - void (*fn)(void); -} iports[4] = { - {MC_INTP_0_SH,tnet_check_completion}, - {MC_INTP_1_SH,reschedule}, - {MC_INTP_2_SH,NULL}, - {MC_INTP_3_SH,NULL}}; - -static inline int rel_cid(unsigned dst) -{ - unsigned dstx, dsty; - unsigned dx,dy; - - if (dst == _cid) return 0; - - dstx = dst % _ncelx; - dsty = dst / _ncelx; - if (dstx >= _cidx) - dx = dstx - _cidx; - else - dx = (_ncelx - _cidx) + dstx; - - if (dsty >= _cidy) - dy = dsty - _cidy; - else - dy = (_ncely - _cidy) + dsty; - - return (dx<<8) | dy; -} - -#define SAVE_PID() \ - unsigned long flags; \ - int saved_pid; \ - save_flags(flags); cli(); \ - saved_pid = MSC_IN(MSC_PID); \ - MSC_OUT(MSC_PID,SYSTEM_CONTEXT); - -#define RESTORE_PID() \ - MSC_OUT(MSC_PID,saved_pid); \ - restore_flags(flags); - - -void ap_put(int dest_cell,u_long local_addr,int size, - u_long remote_addr,u_long dest_flag,u_long local_flag) -{ - volatile u_long *entry; - SAVE_PID(); - - entry = (volatile u_long *)MSC_PUT_QUEUE_S; - - *entry = tnet_rel_cid_table[dest_cell]; - *entry = ((size+3) >> 2); - *entry = (u_long)remote_addr; - *entry = 0; - *entry = (u_long)dest_flag; - *entry = (u_long)local_flag; - *entry = (u_long)local_addr; - *entry = 0; - RESTORE_PID(); -} - -/* remote_addr is physical - local address is virtual - both flags are virtual */ -void ap_phys_put(int dest_cell,u_long local_addr,int size, - u_long remote_addr,u_long dest_flag,u_long local_flag) -{ - volatile u_long *entry; - SAVE_PID(); - - entry = (volatile u_long *)MSC_CPUT_QUEUE_S; - - *entry = tnet_rel_cid_table[dest_cell]; - *entry = ((size+3) >> 2); - *entry = (u_long)remote_addr; - *entry = 0; - *entry = (u_long)dest_flag; - *entry = (u_long)local_flag; - *entry = (u_long)local_addr; - *entry = 0; - RESTORE_PID(); -} - - -/* broadcast put - yeah! */ -void ap_bput(u_long local_addr,int size, - u_long remote_addr,u_long dest_flag,u_long local_flag) -{ - volatile u_long *entry = (volatile u_long *)MSC_XYG_QUEUE_S; - SAVE_PID(); - - *entry = xy_global_head; - *entry = ((size+3) >> 2); - *entry = (u_long)remote_addr; - *entry = 0; - *entry = (u_long)dest_flag; - *entry = (u_long)local_flag; - *entry = (u_long)local_addr; - *entry = 0; - RESTORE_PID(); -} - - -/* remote_addr is physical */ -void ap_phys_bput(u_long local_addr,int size, - u_long remote_addr,u_long dest_flag,u_long local_flag) -{ - volatile u_long *entry = (volatile u_long *)MSC_CXYG_QUEUE_S; - SAVE_PID(); - - *entry = xy_global_head; - *entry = ((size+3) >> 2); - *entry = (u_long)remote_addr; - *entry = 0; - *entry = (u_long)dest_flag; - *entry = (u_long)local_flag; - *entry = (u_long)local_addr; - *entry = 0; - RESTORE_PID(); -} - - - -void ap_get(int dest_cell,u_long local_addr,int size, - u_long remote_addr,u_long local_flag,u_long dest_flag) -{ - volatile u_long *entry; - SAVE_PID(); - - entry = (u_long *)MSC_GET_QUEUE_S; - - *entry = tnet_rel_cid_table[dest_cell]; - *entry = (size+3) >> 2; /* byte --> word */ - *entry = (u_long)local_addr; - *entry = 0; - *entry = (u_long)local_flag; - *entry = (u_long)dest_flag; - *entry = (u_long)remote_addr; - *entry = 0; - RESTORE_PID(); -} - - -/* local_addr is physical - remote_addr is virtual - both flags are virtual -*/ -void ap_phys_get(int dest_cell,u_long local_addr,int size, - u_long remote_addr,u_long local_flag,u_long dest_flag) -{ - volatile u_long *entry; - SAVE_PID(); - - entry = (u_long *)MSC_CGET_QUEUE_S; - - *entry = tnet_rel_cid_table[dest_cell]; - *entry = (size+3) >> 2; /* byte --> word */ - *entry = (u_long)local_addr; - *entry = 0; - *entry = (u_long)local_flag; - *entry = (u_long)dest_flag; - *entry = (u_long)remote_addr; - *entry = 0; - RESTORE_PID(); -} - - -/* - * copy a message from the ringbuffer - being careful of wraparound -*/ -static inline void tnet_copyin(unsigned *dest,unsigned *src,int size) -{ - unsigned *limit = (unsigned *)system_ringbuf.ringbuf + - (SYSTEM_RINGBUF_SIZE>>2); - int size1 = limit - src; - - if (size < size1) - size1 = size; - - size -= size1; - while (size1--) { - *dest++ = *src++; - } - src = system_ringbuf.ringbuf; - while (size--) { - *dest++ = *src++; - } -} - - -/* - put some data into a tasks ringbuffer. size is in words. - */ -static inline void memcpy_to_rbuf(unsigned tid,unsigned *msgp,unsigned size) -{ - struct aplib_struct *aplib; - unsigned octx, ctx; - struct task_struct *tsk; - unsigned room; - - tsk = task[tid]; - if (!tsk || !tsk->aplib) - return; - - octx = srmmu_get_context(); - ctx = MPP_TASK_TO_CTX(tid); - if (octx != ctx) - srmmu_set_context(ctx); - aplib = tsk->aplib; - - if (aplib->write_pointer < aplib->read_pointer) - room = aplib->read_pointer - (aplib->write_pointer+1); - else - room = aplib->ringbuf_size - - ((aplib->write_pointer+1)-aplib->read_pointer); - - if (room < size) { - send_sig(SIGLOST,tsk,1); - goto finished; - } - - tnet_copyin(&aplib->ringbuf[aplib->write_pointer], msgp, size); - - aplib->write_pointer += size; - if (aplib->write_pointer >= aplib->ringbuf_size) - aplib->write_pointer -= aplib->ringbuf_size; - - aplib->rbuf_flag1++; - -finished: - if (octx != ctx) - srmmu_set_context(octx); -} - - - -/* a aplib message has arrived on the system message queue - process - it immediately and return the number of bytes taken by the message in - the system ringbuffer - - Note that this function may be called from interrupt level - */ -static inline void aplib_system_recv(unsigned *msgp) -{ - unsigned tag = msgp[1]>>28; - unsigned size, tid; - - if (tag == RBUF_BIGSEND) { - aplib_bigrecv(msgp); - return; - } - - size = (msgp[0]&0xFFFFF); - tid = (msgp[1]&0x3FF); - - memcpy_to_rbuf(tid,msgp,size+2); -} - - -void tnet_ip_complete(struct sk_buff *skb,int from) -{ -#if IP_DEBUG - char *data = skb->data; - int i; - printk("CID(%d) tnet ip complete from %d\n",_cid,from); - - for (i=0;ilen;i+=4) - printk("(%08x)%c",*(int *)(data+i),i==32?'\n':' '); - printk("\n"); -#endif - /* ap_phys_put(from,(u_long)&dummy,4,MC_INTP_0,0,0); */ - bif_rx(skb); - tnet_stats.bytes_received += skb->len; - tnet_stats.packets_received++; -} - - -static void tnet_ip_recv(int cid,u_long *info) -{ - u_long flag; - u_long ipsize = info[1]; - u_long remote_addr = info[0]; - u_long remote_flag = info[2]; - struct sk_buff *skb = dev_alloc_skb(ipsize+8); - char *p; - - if (!skb) { - ap_put(cid,0,0,0,remote_flag,0); - ap_phys_put(cid,(u_long)&dummy,4,MC_INTP_0,0,0); - tnet_stats.alloc_errors++; - return; - } - - skb_reserve(skb,8); /* align on 16 byte boundary */ - - flag = tnet_add_completion(tnet_ip_complete,(int)skb,(int)cid); - - p = (char *)skb_put(skb,ipsize); -#if 0 -{ - static unsigned count=0; - if (count%500 == 0) - printk("CID(%d) fetching %d bytes from %x to %x\n", - _cid,ipsize,remote_addr,p); - count++; -} -#endif - ap_get(cid,p,ipsize,remote_addr,flag,remote_flag); - ap_phys_get(cid,MC_INTP_0,4,(u_long)&dummy,0,0); -#if IP_DEBUG - printk("CID(%d) ip packet of length %ld from %ld\n",_cid,ipsize,cid); -#endif -} - - -static void tnet_ip_recv_small(u_long *data,int size) -{ - struct sk_buff *skb = dev_alloc_skb(size+8); - if (skb) { - skb_reserve(skb,8); - tnet_copyin((unsigned *)skb_put(skb,size),(unsigned *)data,(size+3)>>2); - bif_rx(skb); - tnet_stats.bytes_received += size; - tnet_stats.packets_received++; - tnet_stats.small_packets_received++; - } else { - tnet_stats.alloc_errors++; - } -} - - -/* we've got an RPC from a remote cell */ -static void tnet_rpc_recv(u_long *data,int size) -{ - struct fnp { - void (*fn)(); - } fnp; - fnp = *(struct fnp *)data; - fnp.fn(data,size); -} - -/* - * receive messages from the system ringbuffer. We don't bother with - * all the niceities that are done in user space, we just always - * process the messages in order - */ -static inline void tnet_recv(void) -{ - unsigned flags; - u_long from,*data,fix,align,size1,size,type; - - if (system_recv_flag == system_recv_count) - return; - - save_flags(flags); cli(); - while (system_recv_flag != system_recv_count) { - u_long read_ptr = - (system_read_ptr + 1) % (SYSTEM_RINGBUF_SIZE>>5); - u_long *msgp = - ((u_long *)system_ringbuf.ringbuf) + (read_ptr<<3); - u_long tag = (msgp[1]>>28) & 0xF; - size1 = (msgp[0]&0xFFFFF)<<2; - - /* move our read pointer past this message */ - system_read_ptr = (system_read_ptr + - ((size1+8+31)>>5))%(SYSTEM_RINGBUF_SIZE>>5); - system_recv_count++; - - - if (tag != RBUF_SYSTEM) { - aplib_system_recv(msgp); - continue; - } - - from = msgp[0] >> 22; - data = msgp+2; - fix = (msgp[0]>>20)&3; - align = (msgp[1]>>26)&3; - size = ((size1 - align) & ~3) | fix; - type = (msgp[1]&0xFF); - - switch (type) { - case TNET_IP: - tnet_ip_recv(from,data); - break; - - case TNET_IP_SMALL: - tnet_ip_recv_small(data,size); - break; - - case TNET_RPC: - tnet_rpc_recv(data,size); - break; - - default: - tnet_stats.errors++; - printk("unknown Tnet type %ld\n",type); - } - -#if DEBUG - printk("CID(%d) recvd %d bytes of type %d read_ptr=%x\n", - _cid,size,type,system_read_ptr); -#endif - } - restore_flags(flags); -} - - -#define COMPLETION_LIST_LENGTH 256 - -static unsigned completion_list_rp = 0; -static unsigned completion_list_wp = 0; - -static volatile struct completion_struct { - u_long flag; - void (*fn)(int a1,...); - u_long args[2]; -} completion_list[COMPLETION_LIST_LENGTH]; - - -void tnet_check_completion(void) -{ - struct completion_struct *cs; - unsigned flags; - - tnet_recv(); - - if (completion_list[completion_list_rp].flag != 2) - return; - - save_flags(flags); cli(); - - while (completion_list[completion_list_rp].flag == 2) { - cs = &completion_list[completion_list_rp]; - cs->flag = 0; - if (++completion_list_rp == COMPLETION_LIST_LENGTH) - completion_list_rp = 0; - - restore_flags(flags); - - cs->fn(cs->args[0],cs->args[1]); - - if (completion_list[completion_list_rp].flag != 2) - return; - - save_flags(flags); cli(); - } - - restore_flags(flags); -} - - -static u_long tnet_add_completion(void (*fn)(int a1,...),int a1,int a2) -{ - unsigned flags; - struct completion_struct *cs; - - save_flags(flags); cli(); - - while (completion_list[completion_list_wp].flag != 0) - tnet_check_completion(); - - cs = &completion_list[completion_list_wp]; - - if (++completion_list_wp == COMPLETION_LIST_LENGTH) - completion_list_wp = 0; - - restore_flags(flags); - - cs->flag = 1; - cs->fn = fn; - cs->args[0] = a1; - cs->args[1] = a2; - - return (u_long)&cs->flag; -} - - -/* - * send a message to the tnet ringuffer on another cell. When the send has - * completed call fn with the args supplied - */ -static void tnet_send(long cid,long type,char *src_addr,long byteSize, - int immediate,u_long flag) -{ - int wordSize; - int byteAlign, byteFix; - u_long src; - u_long info1, info2; - volatile u_long *entry = (volatile u_long *)MSC_SEND_QUEUE_S; - SAVE_PID(); - - byteAlign = ((u_long)src_addr) & 0x3; - byteFix = byteSize & 0x3; - - src = (u_long)src_addr & ~3; - - wordSize = (byteSize + byteAlign + 3) >> 2; - - info1 = (_cid << 22) | (byteFix << 20) | wordSize; - info2 = (RBUF_SYSTEM<<28) | (byteAlign << 26) | type; - - *entry = tnet_rel_cid_table[cid]; - *entry = wordSize; - *entry = (u_long)&system_recv_flag; - *entry = flag; - *entry = (u_long)src; - *entry = 0; - *entry = info1; - *entry = info2; - RESTORE_PID(); - - ap_phys_put(cid,(u_long)&dummy,4,MC_INTP_0,0,0); - if (immediate && flag) - ap_phys_put(_cid,(u_long)&dummy,4,MC_INTP_0,0,0); -} - - -static void free_skb(struct sk_buff *skb, int op) -{ - dev_kfree_skb(skb); -} - -void tnet_send_ip(int cid,struct sk_buff *skb) -{ - char *data = skb->data + sizeof(struct cap_request); - int size = skb->len - sizeof(struct cap_request); - u_long flag; -#if IP_DEBUG - int i; - for (i=0;i TNET_IP_THRESHOLD) { - int *info = (int *)skb->data; /* re-use the header */ - info[0] = (int)data; - info[1] = size; - info[2] = tnet_add_completion(free_skb, (int)skb, 0); - tnet_send(cid,TNET_IP,info,sizeof(int)*3,0,0); - } else { - flag = tnet_add_completion(free_skb, (int)skb, 0); - tnet_send(cid,TNET_IP_SMALL,data,size,0,flag); - tnet_stats.small_packets_sent++; - } - tnet_stats.packets_sent++; - tnet_stats.bytes_sent += size; -#if IP_DEBUG - printk("CID(%d) sent IP of size %d to %d\n",_cid,size,cid); -#endif -} - -static void reschedule(void) -{ - current->need_resched = 1; - mark_bh(TQUEUE_BH); -} - - -/* make a remote procedure call - If free is set then free the data after sending it - The first element of data is presumed to be a function pointer -*/ -int tnet_rpc(int cell,char *data,int size,int free) -{ - unsigned flag=0; - - if (free) { - flag = tnet_add_completion(kfree,data,0); - } - - tnet_send(cell,TNET_RPC,data,size,0,flag); - return 0; -} - - -static void iport_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - int i; - u_long intr = MC_IN(MC_INTR_PORT); - - for (i=0;i<4;i++) { - if (intr & (AP_INTR_REQ << iports[i].shift)) { - MC_OUT(MC_INTR_PORT,AP_CLR_INTR_REQ << iports[i].shift); - if (iports[i].fn) iports[i].fn(); - } - } -} - - -void ap_tnet_init(void) -{ - int i; - - bif_add_debug_key('T',tnet_info,"Tnet status"); - - memset(completion_list,0,sizeof(completion_list)); - - request_irq(APIPORT_IRQ, iport_irq, SA_INTERRUPT, "iport", 0); - - for (i=0;i<4;i++) { - MC_OUT(MC_INTR_PORT,AP_CLR_INTR_REQ << iports[i].shift); - MC_OUT(MC_INTR_PORT,AP_CLR_INTR_MASK << iports[i].shift); - } - - - tnet_rel_cid_table = (int *)kmalloc(sizeof(int)*_ncel,GFP_ATOMIC); - for (i=0;i<_ncel;i++) - tnet_rel_cid_table[i] = rel_cid(i); - - if(_cid == 0) { - xy_global_head = (((_ncelx -1) << 8) & 0xff00) | - ((_ncely - 1) & 0xff); - } - else { - for(i = 1; i < _ncel; i *= 2){ - if(i & _cid) { - int rcidx = (_cid-i)%_ncelx - _cid%_ncelx; - int rcidy = (_cid-i)/_ncelx - _cid/_ncelx; - xy_global_head = ((rcidx << 8) & 0xff00) | - (rcidy & 0xff); - break; - } - } - } -} - -static void tnet_info(void) -{ - struct completion_struct *cs; - - printk( - "errors=%d alloc_errors=%d -bytes_received=%d bytes_sent=%d -packets_received=%d packets_sent=%d -small_received=%d small_sent=%d -", - tnet_stats.errors, tnet_stats.alloc_errors, - tnet_stats.bytes_received, - tnet_stats.bytes_sent, tnet_stats.packets_received, - tnet_stats.packets_sent, tnet_stats.small_packets_received, - tnet_stats.small_packets_sent); - - printk("recv_flag=%d recv_count=%d read_ptr=%d\n", - system_recv_flag,system_recv_count,system_read_ptr); - printk("completion_list_rp=%d completion_list_wp=%d\n", - completion_list_rp,completion_list_wp); -} diff --git a/arch/sparc/ap1000/util.c b/arch/sparc/ap1000/util.c deleted file mode 100644 index 1fe23dc41..000000000 --- a/arch/sparc/ap1000/util.c +++ /dev/null @@ -1,436 +0,0 @@ - /* - * Copyright 1996 The Australian National University. - * Copyright 1996 Fujitsu Laboratories Limited - * - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - */ -/* general utility functions for the AP1000 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APLOG 0 - -struct cap_init cap_init; - -/* find what cell id we are running on */ -int mpp_cid(void) -{ - return(BIF_IN(BIF_CIDR1)); -} - -/* find how many cells there are */ -int mpp_num_cells(void) -{ - return(cap_init.numcells); -} - -/* this can be used to ensure some data is readable before DMAing - it. */ -int ap_verify_data(char *d,int len) -{ - int res = 0; - while (len--) res += *d++; - return res; -} - -/* How many BogoMIPS in the entire machine -Don't worry about float because when it gets this big, it's irrelevant */ -int mpp_agg_bogomips(void) -{ - return mpp_num_cells()*loops_per_sec/500000; /* cheat in working it out */ -} - -/* Puts multiprocessor configuration info into a buffer */ -int get_mppinfo(char *buffer) -{ - return sprintf(buffer, - "Machine Type:\t\t: %s\nNumber of Cells\t\t: %d\nAggregate BogoMIPS\t: %d\n", - "Fujitsu AP1000+", - mpp_num_cells(), - mpp_agg_bogomips()); -} - -#if APLOG -static int do_logging = 0; - - -void ap_log(char *buf,int len) -{ -#define LOG_MAGIC 0x8736526 - static char *logbase; - static char *logptr; - static int logsize = 1024; - int l,i; - - if (buf == NULL && len == -1) { - logbase = kmalloc(logsize + 8,GFP_ATOMIC); - - if (!logbase) { - printk("log init failed\n"); - return; - } - for (i=0;i len) l = len; - memcpy(logptr,buf,l); - len -= l; - logptr += l; - if (logptr == logbase + logsize) - logptr = logbase; - } - *(int *)(logbase - 4) = (logptr - logbase); -} -#endif - -int ap_current_uid = -1; - -/* set output only to a particular uid */ -void ap_set_user(int uid) -{ - ap_current_uid = uid; -} - -/* write some data to a filedescriptor on the front end */ -int ap_write(int fd,char *buf,int nbytes) -{ - struct cap_request req; - - if (nbytes == 0) return 0; - -#if APLOG - ap_log(buf,nbytes); - - if (buf[0] == '|') return nbytes; -#endif - - req.cid = mpp_cid(); - req.type = REQ_WRITE; - req.size = nbytes + sizeof(req); - req.data[0] = fd; - if (ap_current_uid == -1 && current && current->pid) { - req.data[1] = current->uid; - } else { - req.data[1] = ap_current_uid; - } - req.header = MAKE_HEADER(HOST_CID); - - bif_queue(&req,buf,nbytes); - - return(nbytes); -} - -/* write one character to stdout on the front end */ -int ap_putchar(char c) -{ - struct cap_request req; - -#if APLOG - ap_log(&c,1); -#endif - - req.cid = mpp_cid(); - req.type = REQ_PUTCHAR; - req.size = sizeof(req); - req.data[0] = c; - req.header = MAKE_HEADER(HOST_CID); - - bif_queue(&req,0,0); - - return(0); -} - -/* start the debugger (kgdb) on this cell */ -void ap_start_debugger(void) -{ - static int done = 0; - extern void set_debug_traps(void); - extern void breakpoint(void); - if (!done) - set_debug_traps(); - done = 1; - breakpoint(); -} - -void ap_panic(char *msg,int a1,int a2,int a3,int a4,int a5) -{ - ap_led(0xAA); - printk(msg,a1,a2,a3,a4,a5); - ap_start_debugger(); -} - -void ap_printk(char *msg,int a1,int a2,int a3,int a4,int a5) -{ - printk(msg,a1,a2,a3,a4,a5); - /* bif_queue_flush(); */ -} - -/* get the command line arguments from the front end */ -void ap_getbootargs(char *buf) -{ - struct cap_request req; - int size; - - req.cid = mpp_cid(); - req.type = REQ_GETBOOTARGS; - req.size = sizeof(req); - req.header = MAKE_HEADER(HOST_CID); - - write_bif_polled((char *)&req,sizeof(req),NULL,0); - - ap_wait_request(&req,REQ_GETBOOTARGS); - - size = req.size - sizeof(req); - if (size == 0) - buf[0] = '\0'; - else { - read_bif(buf, size); - } - - req.cid = mpp_cid(); - req.type = REQ_INIT; - req.size = sizeof(req); - req.header = MAKE_HEADER(HOST_CID); - - write_bif_polled((char *)&req,sizeof(req),NULL,0); - - ap_wait_request(&req,REQ_INIT); - - if (req.size != sizeof(req)) - read_bif((char *)&cap_init,req.size - sizeof(req)); - if ((req.size - sizeof(req)) != sizeof(cap_init)) - printk("WARNING: Init structure is wrong size, recompile util.c\n"); - - if (cap_init.gdbcell == mpp_cid()) - ap_start_debugger(); - - printk("Got command line arguments from server\n"); -} - -/* a useful utility for debugging pagetable setups */ -void show_mapping_ctx(unsigned *ctp,int context,unsigned Vm) -{ - unsigned *pgtable; - int entry[3]; - int level = 0; - - if (!ctp) ctp = (unsigned *)mmu_p2v(srmmu_get_ctable_ptr()); - - printk("ctp=0x%x ",(int)ctp); - - pgtable = ctp + context; - - /* get the virtual page */ - Vm = Vm>>12; - - printk("Vm page 0x%x is ",Vm); - - entry[0] = Vm>>12; - entry[1] = (Vm>>6) & 0x3f; - entry[2] = Vm & 0x3f; - - while (1) { - -#if 1 - printk("(%08x) ",pgtable[0]); -#endif - - if ((pgtable[0] & 3) == 2) { - printk("mapped at level %d to 0x%x\n",level,pgtable[0]>>8); - return; - } - - if ((pgtable[0] & 3) == 0) { - printk("unmapped at level %d\n",level); - return; - } - - if ((pgtable[0] & 3) == 3) { - printk("invalid at level %d\n",level); - return; - } - - if ((pgtable[0] & 3) == 1) { - pgtable = (unsigned *)(((pgtable[0]>>2)<<6)|0xf0000000); - pgtable += entry[level]; - level++; - } - } -} - - - -static unsigned char current_led = 0; - -void ap_led(unsigned char d) -{ - unsigned paddr = 0x1000; - unsigned word = 0xff & ~d; - current_led = d; - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (word), "r" (paddr), "i" (0x2c) : - "memory"); -} - -void ap_xor_led(unsigned char d) -{ - ap_led(current_led ^ d); -} - -void ap_set_led(unsigned char d) -{ - ap_led(current_led | d); -} - -void ap_unset_led(unsigned char d) -{ - ap_led(current_led & ~d); -} - - -void kbd_put_char(char c) -{ - ap_putchar(c); -} - - -void ap_enter_irq(int irq) -{ - unsigned char v = current_led; - switch (irq) { - case 2: v |= (1<<1); break; - case 4: v |= (1<<2); break; - case 8: v |= (1<<3); break; - case 9: v |= (1<<4); break; - case 10: v |= (1<<5); break; - case 11: v |= (1<<6); break; - default: v |= (1<<7); break; - } - ap_led(v); -} - -void ap_exit_irq(int irq) -{ - unsigned char v = current_led; - switch (irq) { - case 2: v &= ~(1<<1); break; - case 4: v &= ~(1<<2); break; - case 8: v &= ~(1<<3); break; - case 9: v &= ~(1<<4); break; - case 10: v &= ~(1<<5); break; - case 11: v &= ~(1<<6); break; - default: v &= ~(1<<7); break; - } - ap_led(v); -} - - -static DECLARE_WAIT_QUEUE_HEAD(timer_wait); - -static void wait_callback(unsigned long _ignored) -{ - wake_up(&timer_wait); -} - -/* wait till x == *p */ -int wait_on_int(volatile int *p,int x,int interval) -{ - struct timer_list *timer = kmalloc(sizeof(*timer),GFP_KERNEL); - if (!timer) panic("out of memory in wait_on_int()\n"); - timer->next = NULL; - timer->prev = NULL; - timer->data = 0; - timer->function = wait_callback; - while (*p != x) { - timer->expires = jiffies + interval; - add_timer(timer); - interruptible_sleep_on(&timer_wait); - del_timer(timer); - if (signal_pending(current)) - return -EINTR; - } - kfree_s(timer,sizeof(*timer)); - return 0; -} - - -/* an ugly hack to get nfs booting from a central cell to work */ -void ap_nfs_hook(unsigned long server) -{ - unsigned cid = server - cap_init.baseIP; - if (cid < cap_init.bootcid + cap_init.numcells && - cid != mpp_cid()) { - unsigned end = jiffies + 20*HZ; - /* we are booting from another cell */ - printk("waiting for the master cell\n"); - while (time_before(jiffies, end)) ; - printk("continuing\n"); - } -} - -/* convert a IP address to a cell id */ -int ap_ip_to_cid(u_long ip) -{ - unsigned cid; - - if ((ip & cap_init.netmask) != (cap_init.baseIP & cap_init.netmask)) - return -1; - - if ((ip & ~cap_init.netmask) == AP_ALIAS_IP) - cid = cap_init.bootcid; - else - cid = ip - cap_init.baseIP; - if (cid >= cap_init.bootcid + cap_init.numcells) - return -1; - return cid; -} - - -void ap_reboot(char *bootstr) -{ - printk("cell(%d) - don't know how to reboot\n",mpp_cid()); - sti(); - while (1) ; -} - - -void dumb_memset(char *buf,char val,int len) -{ - while (len--) *buf++ = val; -} - -void ap_init_time(struct timeval *xtime) -{ - xtime->tv_sec = cap_init.init_time; - xtime->tv_usec = 0; -} diff --git a/arch/sparc/config.in b/arch/sparc/config.in index 8d3562e37..a983b9a6d 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.81 2000/01/22 05:14:44 zaitcev Exp $ +# $Id: config.in,v 1.84 2000/01/31 21:10:04 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -19,43 +19,33 @@ define_bool CONFIG_VT_CONSOLE y bool 'Symmetric multi-processing support (does not work on sun4/sun4c)' CONFIG_SMP -bool 'Support for AP1000 multicomputer' CONFIG_AP1000 -if [ "$CONFIG_AP1000" = "y" ]; then - define_bool CONFIG_NO_KEYBOARD y - define_bool CONFIG_FDDI y - define_bool CONFIG_APFDDI y - define_bool CONFIG_APBLOCK y - define_bool CONFIG_APBIF y - tristate ' OPIU DDV Driver' CONFIG_DDV -else - bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4 - if [ "$CONFIG_SUN4" != "y" ]; then - bool ' Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI - source drivers/pci/Config.in - fi +bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4 +if [ "$CONFIG_SUN4" != "y" ]; then + bool ' Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI + source drivers/pci/Config.in +fi - mainmenu_option next_comment - comment 'Console drivers' - bool 'PROM console' CONFIG_PROM_CONSOLE - source drivers/video/Config.in - endmenu +mainmenu_option next_comment +comment 'Console drivers' +bool 'PROM console' CONFIG_PROM_CONSOLE +source drivers/video/Config.in +endmenu - # Global things across all Sun machines. - define_bool CONFIG_SBUS y - define_bool CONFIG_SBUSCHAR y - define_bool CONFIG_BUSMOUSE y - define_bool CONFIG_SUN_MOUSE y - define_bool CONFIG_SERIAL y - define_bool CONFIG_SUN_SERIAL y - define_bool CONFIG_SERIAL_CONSOLE y - define_bool CONFIG_SUN_KEYBOARD y - define_bool CONFIG_SUN_CONSOLE y - define_bool CONFIG_SUN_AUXIO y - define_bool CONFIG_SUN_IO y - if [ "$CONFIG_SUN4" != "y" ]; then - source drivers/sbus/char/Config.in - source drivers/sbus/audio/Config.in - fi +# Global things across all Sun machines. +define_bool CONFIG_SBUS y +define_bool CONFIG_SBUSCHAR y +define_bool CONFIG_BUSMOUSE y +define_bool CONFIG_SUN_MOUSE y +define_bool CONFIG_SERIAL y +define_bool CONFIG_SUN_SERIAL y +define_bool CONFIG_SERIAL_CONSOLE y +define_bool CONFIG_SUN_KEYBOARD y +define_bool CONFIG_SUN_CONSOLE y +define_bool CONFIG_SUN_AUXIO y +define_bool CONFIG_SUN_IO y +if [ "$CONFIG_SUN4" != "y" ]; then + source drivers/sbus/char/Config.in + source drivers/sbus/audio/Config.in fi tristate 'Openprom tree appears in /proc/openprom' CONFIG_SUN_OPENPROMFS @@ -161,7 +151,10 @@ if [ "$CONFIG_NET" = "y" ]; then tristate ' Dummy net driver support' CONFIG_DUMMY tristate ' PPP (point-to-point) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then - comment 'CCP compressors for PPP are only built as modules.' + dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m fi tristate ' SLIP (serial line) support' CONFIG_SLIP if [ "$CONFIG_SLIP" != "n" ]; then diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 26037c33e..536d0c5f6 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -14,7 +14,6 @@ CONFIG_EXPERIMENTAL=y CONFIG_VT=y CONFIG_VT_CONSOLE=y # CONFIG_SMP is not set -# CONFIG_AP1000 is not set # CONFIG_SUN4 is not set # CONFIG_PCI is not set @@ -22,7 +21,6 @@ CONFIG_VT_CONSOLE=y # Console drivers # CONFIG_PROM_CONSOLE=y -CONFIG_FB=y # # Frame-buffer support @@ -217,10 +215,10 @@ CONFIG_SCSI_FCAL=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_PPP=m - -# -# CCP compressors for PPP are only built as modules. -# +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y @@ -242,10 +240,12 @@ CONFIG_UNIX98_PTY_COUNT=256 # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m # CONFIG_ADFS_FS is not set CONFIG_AFFS_FS=m # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_BFS_FS_WRITE is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set @@ -256,23 +256,27 @@ CONFIG_ISO9660_FS=m # CONFIG_JOLIET is not set CONFIG_MINIX_FS=m # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set CONFIG_HPFS_FS=m CONFIG_PROC_FS=y CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set CONFIG_ROMFS_FS=m CONFIG_EXT2_FS=y CONFIG_SYSV_FS=m # CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set CONFIG_UFS_FS=m -CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # CONFIG_CODA_FS=m CONFIG_NFS_FS=y +# CONFIG_ROOT_NFS is not set CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y @@ -295,7 +299,6 @@ CONFIG_NCP_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SGI_PARTITION is not set CONFIG_SUN_PARTITION=y CONFIG_NLS=y diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S index eb3d007f0..56b3da66a 100644 --- a/arch/sparc/kernel/head.S +++ b/arch/sparc/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.101 1999/12/02 08:34:56 jj Exp $ +/* $Id: head.S,v 1.102 2000/01/29 01:08:54 anton Exp $ * head.S: The initial boot code for the Sparc port of Linux. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -483,10 +483,8 @@ current_pc: 1: mov %o7, %g3 -#ifndef CONFIG_AP1000 tst %o0 be no_sun4u_here -#endif mov %g4, %o7 /* Previous %o7. */ mov %o0, %l0 ! stash away romvec @@ -762,11 +760,6 @@ go_to_highmem: * I figure out and store nwindows and nwindowsm1 later on. */ execute_in_high_mem: -#if CONFIG_AP1000 - /* we don't have a prom :-( */ - b sun4m_init - nop -#endif mov %l0, %o0 ! put back romvec mov %l1, %o1 ! and debug_vec diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index c0ffb2675..61a51f103 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.29 2000/01/22 07:35:25 zaitcev Exp $ +/* $Id: ioport.c,v 1.30 2000/01/28 13:41:55 jj Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index c89d04872..8e8fab320 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.99 1999/12/27 06:08:29 anton Exp $ +/* $Id: irq.c,v 1.100 2000/01/29 01:38:04 anton Exp $ * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the * Sparc the IRQ's are basically 'cast in stone' * and you are supposed to probe the prom's device @@ -739,12 +739,6 @@ void __init init_IRQ(void) sun4d_init_IRQ(); break; - case ap1000: -#if CONFIG_AP1000 - ap_init_IRQ();; - break; -#endif - default: prom_printf("Cannot initialize IRQ's on this Sun machine..."); break; diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 420efe1e1..c24d8649c 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.144 2000/01/21 11:38:39 jj Exp $ +/* $Id: process.c,v 1.145 2000/01/29 01:08:56 anton Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -266,9 +266,6 @@ void show_stackframe(struct sparc_stackf *sf) void show_regs(struct pt_regs * regs) { -#if __MPP__ - printk("CID: %d\n",mpp_cid()); -#endif printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx\n", regs->psr, regs->pc, regs->npc, regs->y); printk("g0: %08lx g1: %08lx g2: %08lx g3: %08lx ", diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 60928d7aa..50d682929 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.113 1999/12/16 14:37:35 anton Exp $ +/* $Id: setup.c,v 1.114 2000/01/29 01:08:57 anton Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -200,11 +200,6 @@ static void __init boot_flags_init(char *commands) boot_flags |= BOOTME_KGDBB; prom_printf("KGDB: Using serial line /dev/ttyb.\n"); break; -#endif -#ifdef CONFIG_AP1000 - case 'c': - printk("KGDB: AP1000+ debugging\n"); - break; #endif default: printk("KGDB: Unknown tty line.\n"); @@ -325,10 +320,6 @@ void __init setup_arch(char **cmdline_p) prom_printf("This kernel is for Sun4 architecture only.\n"); prom_halt(); } -#endif -#if CONFIG_AP1000 - sparc_cpu_model=ap1000; - strcpy(&cputypval, "ap+"); #endif printk("ARCH: "); switch(sparc_cpu_model) { @@ -350,10 +341,6 @@ void __init setup_arch(char **cmdline_p) case sun4u: printk("SUN4U\n"); break; - case ap1000: - register_console(&prom_console); - printk("AP1000\n"); - break; default: printk("UNKNOWN!\n"); break; diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index b8cdd3749..8df494f2d 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.87 2000/01/21 17:41:14 anton Exp $ +/* $Id: sparc_ksyms.c,v 1.88 2000/01/28 13:41:55 jj Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 4dcb7866a..3815cae1b 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.57 2000/01/21 11:38:42 jj Exp $ +/* $Id: sys_sparc.c,v 1.59 2000/01/29 07:40:10 davem Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -383,12 +383,3 @@ done: up_read(&uts_sem); return err; } - - -#ifndef CONFIG_AP1000 -/* only AP+ systems have sys_aplib */ -asmlinkage int sys_aplib(void) -{ - return -ENOSYS; -} -#endif diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 15f38bd5e..bb3a5ad36 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.111 2000/01/22 05:17:55 anton Exp $ +/* $Id: sys_sunos.c,v 1.112 2000/01/29 07:40:11 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 47aea979b..174522d03 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.91 2000/01/16 06:20:44 davem Exp $ +/* $Id: systbls.S,v 1.93 2000/01/29 16:41:18 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -47,7 +47,7 @@ sys_call_table: /*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall /*135*/ .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64 /*140*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getrlimit -/*145*/ .long sys_setrlimit, sys_nis_syscall, sys_prctl, sys_pciconfig_read, sys_pciconfig_write +/*145*/ .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write /*150*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall /*155*/ .long sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount /*160*/ .long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall @@ -70,7 +70,7 @@ sys_call_table: /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl -/*255*/ .long sys_aplib, sys_nis_syscall +/*255*/ .long sys_nis_syscall, sys_nis_syscall #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -164,6 +164,6 @@ sunos_sys_table: .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys /*250*/ .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys, sunos_nosys, sys_aplib + .long sunos_nosys, sunos_nosys, sunos_nosys #endif diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 295988f58..3e52fef95 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.50 2000/01/21 04:35:53 anton Exp $ +/* $Id: time.c,v 1.51 2000/01/29 01:08:59 anton Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -353,12 +353,6 @@ void __init sbus_time_init(void) BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM); btfixup(); -#if CONFIG_AP1000 - init_timers(timer_interrupt); - ap_init_time(&xtime); - return; -#endif - if (ARCH_SUN4) sun4_clock_probe(); else @@ -451,14 +445,6 @@ extern __inline__ unsigned long do_gettimeoffset(void) */ void do_gettimeofday(struct timeval *tv) { -#if CONFIG_AP1000 - unsigned long flags; - - save_and_cli(flags); - ap_gettimeofday(&xtime); - *tv = xtime; - restore_flags(flags); -#else /* !(CONFIG_AP1000) */ /* Load doubles must be used on xtime so that what we get * is guarenteed to be atomic, this is why we can run this * with interrupts on full blast. Don't touch this... -DaveM @@ -493,7 +479,6 @@ void do_gettimeofday(struct timeval *tv) sub %o5, %o2, %o5 st %o4, [%o0 + 0x0] 1: st %o5, [%o0 + 0x4]"); -#endif } void do_settimeofday(struct timeval *tv) @@ -505,13 +490,11 @@ void do_settimeofday(struct timeval *tv) static void sbus_do_settimeofday(struct timeval *tv) { -#if !CONFIG_AP1000 tv->tv_usec -= do_gettimeoffset(); if(tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } -#endif xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 5e304411c..00a4f35d2 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.35 1999/10/09 05:32:01 zaitcev Exp $ +# $Id: Makefile,v 1.36 2000/01/29 01:09:05 anton Exp $ # Makefile for the linux Sparc-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also @@ -9,9 +9,6 @@ O_TARGET := mm.o O_OBJS := fault.o init.o loadmmu.o generic.o extable.o btfixup.o -ifeq ($(CONFIG_AP1000),y) -O_OBJS += asyncd.o -endif ifeq ($(CONFIG_SUN4),y) O_OBJS += nosrmmu.o else diff --git a/arch/sparc/mm/asyncd.c b/arch/sparc/mm/asyncd.c deleted file mode 100644 index 0034cb60b..000000000 --- a/arch/sparc/mm/asyncd.c +++ /dev/null @@ -1,290 +0,0 @@ -/* $Id: asyncd.c,v 1.20 2000/01/21 11:38:47 jj Exp $ - * The asyncd kernel daemon. This handles paging on behalf of - * processes that receive page faults due to remote (async) memory - * accesses. - * - * Idea and skeleton code courtesy of David Miller (bless his cotton socks) - * - * Implemented by tridge - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include /* for cli()/sti() */ -#include /* for memcpy_to/fromfs */ -#include -#include -#include - -#define DEBUG 0 - -#define WRITE_LIMIT 100 -#define LOOP_LIMIT 200 - -static struct { - int faults, read, write, success, failure, errors; -} stats; - -/* - * The wait queue for waking up the async daemon: - */ -static DECLARE_WAIT_QUEUE_HEAD(asyncd_wait); - -struct async_job { - volatile struct async_job *next; - int taskid; - struct mm_struct *mm; - unsigned long address; - int write; - void (*callback)(int,unsigned long,int,int); -}; - -static volatile struct async_job *async_queue = NULL; -static volatile struct async_job *async_queue_end = NULL; - -static void add_to_async_queue(int taskid, - struct mm_struct *mm, - unsigned long address, - int write, - void (*callback)(int,unsigned long,int,int)) -{ - struct async_job *a = kmalloc(sizeof(*a),GFP_ATOMIC); - - if (!a) { - printk("ERROR: out of memory in asyncd\n"); - a->callback(taskid,address,write,1); - return; - } - - if (write) - stats.write++; - else - stats.read++; - - a->next = NULL; - a->taskid = taskid; - a->mm = mm; - a->address = address; - a->write = write; - a->callback = callback; - - if (!async_queue) { - async_queue = a; - } else { - async_queue_end->next = a; - } - async_queue_end = a; -} - - -void async_fault(unsigned long address, int write, int taskid, - void (*callback)(int,unsigned long,int,int)) -{ - struct task_struct *tsk = task[taskid]; - struct mm_struct *mm = tsk->mm; - - stats.faults++; - -#if 0 - printk("paging in %x for task=%d\n",address,taskid); -#endif - - add_to_async_queue(taskid, mm, address, write, callback); - wake_up(&asyncd_wait); - mark_bh(TQUEUE_BH); -} - -static int fault_in_page(int taskid, - struct vm_area_struct *vma, - unsigned address,int write) -{ - static unsigned last_address; - static int last_task, loop_counter; - struct task_struct *tsk = task[taskid]; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - siginfo_t info; - - if (!tsk || !tsk->mm) - return 1; - - if (!vma || (write && !(vma->vm_flags & VM_WRITE))) - goto bad_area; - if (vma->vm_start > address) - goto bad_area; - - if (address == last_address && taskid == last_task) { - loop_counter++; - } else { - loop_counter = 0; - last_address = address; - last_task = taskid; - } - - if (loop_counter == WRITE_LIMIT && !write) { - printk("MSC bug? setting write request\n"); - stats.errors++; - write = 1; - } - - if (loop_counter == LOOP_LIMIT) { - printk("MSC bug? failing request\n"); - stats.errors++; - return 1; - } - - pgd = pgd_offset(vma->vm_mm, address); - pmd = pmd_alloc(pgd,address); - if(!pmd) - goto no_memory; - pte = pte_alloc(pmd, address); - if(!pte) - goto no_memory; - if(!pte_present(*pte)) { - handle_mm_fault(tsk, vma, address, write); - goto finish_up; - } - set_pte(pte, pte_mkyoung(*pte)); - flush_tlb_page(vma, address); - if(!write) - goto finish_up; - if(pte_write(*pte)) { - set_pte(pte, pte_mkdirty(*pte)); - flush_tlb_page(vma, address); - goto finish_up; - } - handle_mm_fault(tsk, vma, address, write); - - /* Fall through for do_wp_page */ -finish_up: - stats.success++; - return 0; - -no_memory: - stats.failure++; - oom(tsk); - return 1; - -bad_area: - stats.failure++; - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = SEGV_MAPERR; - info.si_addr = (void *)address; - info.si_trapno = 0; - send_sig_info(SIGSEGV, &info, tsk); - return 1; -} - - -/* Note the semaphore operations must be done here, and _not_ - * in async_fault(). - */ -static void run_async_queue(void) -{ - int ret; - unsigned flags; - - while (async_queue) { - volatile struct async_job *a; - struct mm_struct *mm; - struct vm_area_struct *vma; - - save_flags(flags); cli(); - a = async_queue; - async_queue = async_queue->next; - restore_flags(flags); - - mm = a->mm; - - down(&mm->mmap_sem); - vma = find_vma(mm, a->address); - ret = fault_in_page(a->taskid,vma,a->address,a->write); -#if DEBUG - printk("fault_in_page(task=%d addr=%x write=%d) = %d\n", - a->taskid,a->address,a->write,ret); -#endif - a->callback(a->taskid,a->address,a->write,ret); - up(&mm->mmap_sem); - kfree_s((void *)a,sizeof(*a)); - } -} - - -#if CONFIG_AP1000 -static void asyncd_info(void) -{ - printk("CID(%d) faults: total=%d read=%d write=%d success=%d fail=%d err=%d\n", - mpp_cid(),stats.faults, stats.read, stats.write, stats.success, - stats.failure, stats.errors); -} -#endif - - -/* - * The background async daemon. - * Started as a kernel thread from the init process. - */ -int asyncd(void *unused) -{ - current->session = 1; - current->pgrp = 1; - sprintf(current->comm, "asyncd"); - sigfillset(¤t->blocked); /* block all signals */ - recalc_sigpending(current); - - /* Give asyncd a realtime priority. */ - current->policy = SCHED_FIFO; - current->priority = 32; /* Fixme --- we need to standardise our - namings for POSIX.4 realtime scheduling - priorities. */ - - printk("Started asyncd\n"); - -#if CONFIG_AP1000 - bif_add_debug_key('a',asyncd_info,"stats on asyncd"); -#endif - - while (1) { - unsigned flags; - - save_flags(flags); cli(); - - while (!async_queue) { - spin_lock(¤t->sigmask_lock); - flush_signals(current); - spin_unlock(¤t->sigmask_lock); - interruptible_sleep_on(&asyncd_wait); - __sti(); cli(); - } - - restore_flags(flags); - - run_async_queue(); - } -} - -#if CONFIG_AP1000 - -static int __init init_ap1000(void) -{ - kernel_thread(asyncd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - return 0; -} - -module_init(init_ap1000) - -#endif diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 3fc96ef14..9e9a225a5 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.78 2000/01/24 03:22:38 anton Exp $ +/* $Id: init.c,v 1.79 2000/01/29 01:09:06 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -238,15 +238,6 @@ void __init paging_init(void) sparc_unmapped_base = 0x50000000; BTFIXUPSET_SETHI(sparc_unmapped_base, 0x50000000); break; - - case ap1000: -#if CONFIG_AP1000 - apmmu_paging_init(); - sparc_unmapped_base = 0x50000000; - BTFIXUPSET_SETHI(sparc_unmapped_base, 0x50000000); - break; -#endif - default: prom_printf("paging_init: Cannot init paging on this Sparc\n"); prom_printf("paging_init: sparc_cpu_model = %d\n", sparc_cpu_model); diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c index 3338666e8..ce0885679 100644 --- a/arch/sparc/mm/loadmmu.c +++ b/arch/sparc/mm/loadmmu.c @@ -1,4 +1,4 @@ -/* $Id: loadmmu.c,v 1.53 2000/01/09 10:46:50 anton Exp $ +/* $Id: loadmmu.c,v 1.54 2000/01/29 01:09:07 anton Exp $ * loadmmu.c: This code loads up all the mm function pointers once the * machine type has been determined. It also sets the static * mmu values such as PAGE_NONE, etc. @@ -39,11 +39,6 @@ void __init load_mmu(void) case sun4d: ld_mmu_srmmu(); break; - case ap1000: -#if CONFIG_AP1000 - ld_mmu_apmmu(); - break; -#endif default: prom_printf("load_mmu: %d unsupported\n", (int)sparc_cpu_model); prom_halt(); diff --git a/arch/sparc/prom/bootstr.c b/arch/sparc/prom/bootstr.c index 5edcad9d2..a4a040ca2 100644 --- a/arch/sparc/prom/bootstr.c +++ b/arch/sparc/prom/bootstr.c @@ -1,4 +1,4 @@ -/* $Id: bootstr.c,v 1.18 1999/08/31 06:54:45 davem Exp $ +/* $Id: bootstr.c,v 1.19 2000/01/29 01:09:11 anton Exp $ * bootstr.c: Boot string/argument acquisition from the PROM. * * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -55,11 +55,6 @@ prom_getbootargs(void) */ strncpy(barg_buf, *romvec->pv_v2bootargs.bootargs, BARG_LEN-1); break; - case PROM_AP1000: -#if CONFIG_AP1000 - ap_getbootargs(barg_buf, BARG_LEN); - break; -#endif default: break; } diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c index 4a1a42309..2305dc858 100644 --- a/arch/sparc/prom/console.c +++ b/arch/sparc/prom/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.20 1998/09/21 05:05:50 jj Exp $ +/* $Id: console.c,v 1.21 2000/01/29 01:09:12 anton Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * @@ -45,7 +45,6 @@ prom_nbgetchar(void) i = -1; } break; - case PROM_AP1000: default: i = -1; break; @@ -79,15 +78,6 @@ prom_nbputchar(char c) else i = -1; break; - case PROM_AP1000: -#if CONFIG_AP1000 - { - extern void ap_putchar(char ); - ap_putchar(c); - i = 0; - } -#endif - break; default: i = -1; break; @@ -160,8 +150,6 @@ prom_query_input_device() return PROMDEV_ITTYB; } return PROMDEV_I_UNK; - case PROM_AP1000: - return PROMDEV_I_UNK; } } @@ -219,7 +207,6 @@ prom_query_output_device() }; } break; - case PROM_AP1000: default: } return PROMDEV_O_UNK; diff --git a/arch/sparc/prom/devops.c b/arch/sparc/prom/devops.c index c273b9922..5a58efa0b 100644 --- a/arch/sparc/prom/devops.c +++ b/arch/sparc/prom/devops.c @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.11 1998/03/09 14:04:24 jj Exp $ +/* $Id: devops.c,v 1.12 2000/01/29 01:09:12 anton Exp $ * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -31,7 +31,6 @@ prom_devopen(char *dstr) case PROM_V3: handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr); break; - case PROM_AP1000: default: handle = -1; break; @@ -56,7 +55,6 @@ prom_devclose(int dhandle) case PROM_V3: (*(romvec->pv_v2devops.v2_dev_close))(dhandle); break; - case PROM_AP1000: default: break; }; @@ -81,7 +79,6 @@ prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) case PROM_V3: (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo); break; - case PROM_AP1000: default: break; }; diff --git a/arch/sparc/prom/init.c b/arch/sparc/prom/init.c index 0802a97e5..b83409c81 100644 --- a/arch/sparc/prom/init.c +++ b/arch/sparc/prom/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.13 1999/08/31 06:54:45 davem Exp $ +/* $Id: init.c,v 1.14 2000/01/29 01:09:12 anton Exp $ * init.c: Initialize internal variables used by the PROM * library functions. * @@ -40,10 +40,6 @@ void __init prom_init(struct linux_romvec *rp) #ifdef CONFIG_SUN4 extern struct linux_romvec *sun4_prom_init(void); rp = sun4_prom_init(); -#endif -#if CONFIG_AP1000 - extern struct linux_romvec *ap_prom_init(void); - rp = ap_prom_init(); #endif romvec = rp; @@ -60,10 +56,6 @@ void __init prom_init(struct linux_romvec *rp) case 40: prom_vers = PROM_SUN4; break; - case 42: /* why not :-) */ - prom_vers = PROM_AP1000; - break; - default: prom_printf("PROMLIB: Bad PROM version %d\n", romvec->pv_romvers); diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index c2f311df6..5480edb9c 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c @@ -1,4 +1,4 @@ -/* $Id: memory.c,v 1.14 1999/08/31 06:54:46 davem Exp $ +/* $Id: memory.c,v 1.15 2000/01/29 01:09:12 anton Exp $ * memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * @@ -194,19 +194,6 @@ void __init prom_meminit(void) #endif break; - case PROM_AP1000: -#if CONFIG_AP1000 - /* really simple memory map */ - prom_phys_total[0].start_adr = 0x00000000; - prom_phys_total[0].num_bytes = ap_memory_size(); - prom_phys_total[0].theres_more = 0x0; - prom_prom_taken[0].start_adr = 0x00000000; - prom_prom_taken[0].num_bytes = 0x00000000; - prom_prom_taken[0].theres_more = 0x0; - prom_phys_avail[0].start_adr = 0x00000000; - prom_phys_avail[0].num_bytes = prom_phys_total[0].num_bytes; - prom_phys_avail[0].theres_more = 0x0; -#endif default: break; }; diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c index 2346e3564..ba624673f 100644 --- a/arch/sparc/prom/mp.c +++ b/arch/sparc/prom/mp.c @@ -1,4 +1,4 @@ -/* $Id: mp.c,v 1.10 1998/03/09 14:04:26 jj Exp $ +/* $Id: mp.c,v 1.11 2000/01/29 01:09:12 anton Exp $ * mp.c: OpenBoot Prom Multiprocessor support routines. Don't call * these on a UP or else you will halt and catch fire. ;) * @@ -29,7 +29,6 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha switch(prom_vers) { case PROM_V0: case PROM_V2: - case PROM_AP1000: default: ret = -1; break; @@ -56,7 +55,6 @@ prom_stopcpu(int cpunode) switch(prom_vers) { case PROM_V0: case PROM_V2: - case PROM_AP1000: default: ret = -1; break; @@ -83,7 +81,6 @@ prom_idlecpu(int cpunode) switch(prom_vers) { case PROM_V0: case PROM_V2: - case PROM_AP1000: default: ret = -1; break; @@ -110,7 +107,6 @@ prom_restartcpu(int cpunode) switch(prom_vers) { case PROM_V0: case PROM_V2: - case PROM_AP1000: default: ret = -1; break; diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index 72a6cd6cc..24ac381a8 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c @@ -1,4 +1,4 @@ -/* $Id: printf.c,v 1.5 1996/04/04 16:31:07 tridge Exp $ +/* $Id: printf.c,v 1.6 2000/01/29 01:09:12 anton Exp $ * printf.c: Internal prom library printf facility. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -28,16 +28,12 @@ prom_printf(char *fmt, ...) bptr = ppbuf; -#if CONFIG_AP1000 - ap_write(1,bptr,strlen(bptr)); -#else while((ch = *(bptr++)) != 0) { if(ch == '\n') prom_putchar('\r'); prom_putchar(ch); } -#endif va_end(args); return; } diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index ace1366ba..fdf3960e3 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.87 2000/01/16 06:18:53 davem Exp $ +# $Id: config.in,v 1.89 2000/01/31 21:10:10 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 59db5d4bc..3e841d71b 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -292,6 +292,7 @@ CONFIG_VIDEO_DEV=y # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m # CONFIG_ADFS_FS is not set CONFIG_AFFS_FS=m # CONFIG_HFS_FS is not set @@ -307,10 +308,12 @@ CONFIG_ISO9660_FS=m # CONFIG_JOLIET is not set CONFIG_MINIX_FS=m # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set CONFIG_HPFS_FS=m CONFIG_PROC_FS=y CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set CONFIG_ROMFS_FS=m CONFIG_EXT2_FS=y CONFIG_SYSV_FS=m @@ -318,15 +321,16 @@ CONFIG_SYSV_FS=m CONFIG_UDF_FS=m # CONFIG_UDF_RW is not set CONFIG_UFS_FS=m -CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # CONFIG_CODA_FS=m CONFIG_NFS_FS=y +# CONFIG_ROOT_NFS is not set CONFIG_NFSD=m -CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m @@ -347,7 +351,6 @@ CONFIG_NCP_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SGI_PARTITION is not set CONFIG_SUN_PARTITION=y CONFIG_NLS=y diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c index 76516f2f2..59b48600d 100644 --- a/arch/sparc64/kernel/binfmt_elf32.c +++ b/arch/sparc64/kernel/binfmt_elf32.c @@ -1,7 +1,7 @@ /* * binfmt_elf32.c: Support 32-bit Sparc ELF binaries on Ultra. * - * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) */ diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S index 81f4fd366..9c1818c5e 100644 --- a/arch/sparc64/kernel/dtlb_backend.S +++ b/arch/sparc64/kernel/dtlb_backend.S @@ -1,8 +1,8 @@ -/* $Id: dtlb_backend.S,v 1.8 1999/12/05 10:41:35 davem Exp $ +/* $Id: dtlb_backend.S,v 1.9 2000/01/31 04:59:12 davem Exp $ * dtlb_backend.S: Back end to DTLB miss replacement strategy. * This is included directly into the trap table. * - * Copyright (C) 1996,1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com) * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) */ diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S index 71e5b14d7..0f86bc896 100644 --- a/arch/sparc64/kernel/dtlb_base.S +++ b/arch/sparc64/kernel/dtlb_base.S @@ -1,8 +1,8 @@ -/* $Id: dtlb_base.S,v 1.4 1998/06/15 16:59:30 jj Exp $ +/* $Id: dtlb_base.S,v 1.5 2000/01/31 04:59:12 davem Exp $ * dtlb_base.S: Front end to DTLB miss replacement strategy. * This is included directly into the trap table. * - * Copyright (C) 1996,1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com) * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) */ diff --git a/arch/sparc64/kernel/dtlb_prot.S b/arch/sparc64/kernel/dtlb_prot.S index 067a1d051..73f3596e1 100644 --- a/arch/sparc64/kernel/dtlb_prot.S +++ b/arch/sparc64/kernel/dtlb_prot.S @@ -1,8 +1,8 @@ -/* $Id: dtlb_prot.S,v 1.18 1999/03/02 15:42:14 jj Exp $ +/* $Id: dtlb_prot.S,v 1.19 2000/01/31 04:59:12 davem Exp $ * dtlb_prot.S: DTLB protection trap strategy. * This is included directly into the trap table. * - * Copyright (C) 1996,1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com) * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) */ diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index 7a7315003..d51e36f61 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.74 2000/01/15 04:47:48 davem Exp $ +/* $Id: ioctl32.c,v 1.76 2000/01/31 21:10:15 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c index d1041b85f..27aa136ff 100644 --- a/arch/sparc64/kernel/iommu_common.c +++ b/arch/sparc64/kernel/iommu_common.c @@ -1,4 +1,4 @@ -/* $Id: iommu_common.c,v 1.2 1999/12/19 09:17:53 davem Exp $ +/* $Id: iommu_common.c,v 1.3 2000/01/28 13:41:59 jj Exp $ * iommu_common.c: UltraSparc SBUS/PCI common iommu code. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) diff --git a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S index eefc1c074..4ef509731 100644 --- a/arch/sparc64/kernel/itlb_base.S +++ b/arch/sparc64/kernel/itlb_base.S @@ -1,8 +1,8 @@ -/* $Id: itlb_base.S,v 1.7 1999/03/02 15:42:12 jj Exp $ +/* $Id: itlb_base.S,v 1.8 2000/01/31 04:59:12 davem Exp $ * itlb_base.S: Front end to ITLB miss replacement strategy. * This is included directly into the trap table. * - * Copyright (C) 1996,1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com) * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) */ diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index e72671428..409a44897 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -1,4 +1,4 @@ -/* $Id: pci_iommu.c,v 1.7 1999/12/20 14:08:15 jj Exp $ +/* $Id: pci_iommu.c,v 1.8 2000/01/28 13:41:59 jj Exp $ * pci_iommu.c: UltraSparc PCI controller IOM/STC support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 559769b87..1ff768056 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1,4 +1,4 @@ -/* $Id: pci_psycho.c,v 1.9 2000/01/11 23:38:32 davem Exp $ +/* $Id: pci_psycho.c,v 1.10 2000/01/28 13:42:00 jj Exp $ * pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 2f82de9ce..44247c371 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1,4 +1,4 @@ -/* $Id: pci_sabre.c,v 1.10 2000/01/11 23:38:35 davem Exp $ +/* $Id: pci_sabre.c,v 1.11 2000/01/28 13:42:01 jj Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index a73387754..38e731f37 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.6 1999/12/20 14:08:17 jj Exp $ +/* $Id: sbus.c,v 1.7 2000/01/28 13:41:58 jj Exp $ * sbus.c: UltraSparc SBUS controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 418b2f7b2..c48a1f6e4 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.70 2000/01/07 18:15:18 jj Exp $ +/* $Id: sparc64_ksyms.c,v 1.72 2000/01/28 13:41:59 jj Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -124,11 +124,6 @@ EXPORT_SYMBOL_PRIVATE(write_lock); EXPORT_SYMBOL_PRIVATE(write_unlock); #endif -/* rw semaphores */ -EXPORT_SYMBOL_NOVERS(__down_read_failed); -EXPORT_SYMBOL_NOVERS(__down_write_failed); -EXPORT_SYMBOL_NOVERS(__rwsem_wake); - /* Kernel wide locking */ EXPORT_SYMBOL(kernel_flag); @@ -169,6 +164,11 @@ EXPORT_SYMBOL(local_irq_count); EXPORT_SYMBOL(local_bh_count); #endif +/* rw semaphores */ +EXPORT_SYMBOL_NOVERS(__down_read_failed); +EXPORT_SYMBOL_NOVERS(__down_write_failed); +EXPORT_SYMBOL_NOVERS(__rwsem_wake); + /* Atomic counter implementation. */ EXPORT_SYMBOL_PRIVATE(atomic_add); EXPORT_SYMBOL_PRIVATE(atomic_sub); diff --git a/arch/sparc64/kernel/starfire.c b/arch/sparc64/kernel/starfire.c index 3237b37dc..8ff7ea4d2 100644 --- a/arch/sparc64/kernel/starfire.c +++ b/arch/sparc64/kernel/starfire.c @@ -1,7 +1,7 @@ -/* $Id: starfire.c,v 1.4 1999/09/21 14:35:25 davem Exp $ +/* $Id: starfire.c,v 1.5 2000/01/31 04:59:12 davem Exp $ * starfire.c: Starfire/E10000 support. * - * Copyright (C) 1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1998 David S. Miller (davem@redhat.com) */ #include diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 3c3a5c1c6..be2638ec9 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.34 2000/01/21 11:39:06 jj Exp $ +/* $Id: sys_sparc.c,v 1.35 2000/01/29 07:40:12 davem Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 6beb0531f..62058ffcf 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.37 2000/01/21 11:39:03 jj Exp $ +/* $Id: sys_sunos32.c,v 1.38 2000/01/29 07:40:13 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 2c61f6623..10effccae 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.66 2000/01/16 06:20:48 davem Exp $ +/* $Id: systbls.S,v 1.67 2000/01/29 16:41:21 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -48,7 +48,7 @@ sys_call_table32: /*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall .word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64 /*140*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getrlimit - .word sys32_setrlimit, sys_nis_syscall, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write + .word sys32_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write /*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall .word sys_nis_syscall, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount /*160*/ .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall @@ -107,7 +107,7 @@ sys_call_table: /*130*/ .word sys_ftruncate, sys_flock, sys_nis_syscall, sys_sendto, sys_shutdown .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_nis_syscall /*140*/ .word sys_nis_syscall, sys_getpeername, sys_nis_syscall, sys_nis_syscall, sys_getrlimit - .word sys_setrlimit, sys_nis_syscall, sys_prctl, sys_pciconfig_read, sys_pciconfig_write + .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write /*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount /*160*/ .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c index 315724ec3..518281daa 100644 --- a/arch/sparc64/lib/debuglocks.c +++ b/arch/sparc64/lib/debuglocks.c @@ -1,7 +1,7 @@ -/* $Id: debuglocks.c,v 1.3 1999/09/10 10:40:50 davem Exp $ +/* $Id: debuglocks.c,v 1.4 2000/01/31 04:59:10 davem Exp $ * debuglocks.c: Debugging versions of SMP locking primitives. * - * Copyright (C) 1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1998 David S. Miller (davem@redhat.com) */ #include diff --git a/arch/sparc64/lib/memscan.S b/arch/sparc64/lib/memscan.S index 423bc1409..a34c6b9d2 100644 --- a/arch/sparc64/lib/memscan.S +++ b/arch/sparc64/lib/memscan.S @@ -1,8 +1,8 @@ -/* $Id: memscan.S,v 1.2 1998/05/21 14:42:22 jj Exp $ +/* $Id: memscan.S,v 1.3 2000/01/31 04:59:10 davem Exp $ * memscan.S: Optimized memscan for Sparc64. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) - * Copyright (C) 1998 David S. Miller (davem@dm.cobaltmicro.com) + * Copyright (C) 1998 David S. Miller (davem@redhat.com) */ #define HI_MAGIC 0x8080808080808080 diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile index a7448f1db..d97c47778 100644 --- a/arch/sparc64/mm/Makefile +++ b/arch/sparc64/mm/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.5 1998/07/26 03:02:54 davem Exp $ +# $Id: Makefile,v 1.6 2000/01/31 01:30:49 davem Exp $ # Makefile for the linux Sparc64-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also @@ -14,6 +14,6 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o O_TARGET := mm.o -O_OBJS := ultra.o fault.o init.o generic.o asyncd.o extable.o modutil.o +O_OBJS := ultra.o fault.o init.o generic.o extable.o modutil.o include $(TOPDIR)/Rules.make diff --git a/arch/sparc64/mm/asyncd.c b/arch/sparc64/mm/asyncd.c deleted file mode 100644 index b87efd590..000000000 --- a/arch/sparc64/mm/asyncd.c +++ /dev/null @@ -1,283 +0,0 @@ -/* $Id: asyncd.c,v 1.12 2000/01/21 11:39:13 jj Exp $ - * The asyncd kernel daemon. This handles paging on behalf of - * processes that receive page faults due to remote (async) memory - * accesses. - * - * Idea and skeleton code courtesy of David Miller (bless his cotton socks) - * - * Implemented by tridge - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include /* for cli()/sti() */ -#include /* for memcpy_to/fromfs */ -#include -#include -#include - -#define DEBUG 0 - -#define WRITE_LIMIT 100 -#define LOOP_LIMIT 200 - -static struct { - int faults, read, write, success, failure, errors; -} stats; - -/* - * The wait queue for waking up the async daemon: - */ -static DECLARE_WAIT_QUEUE_HEAD(asyncd_wait); - -struct async_job { - volatile struct async_job *next; - int taskid; - struct mm_struct *mm; - unsigned long address; - int write; - void (*callback)(int,unsigned long,int,int); -}; - -static volatile struct async_job *async_queue = NULL; -static volatile struct async_job *async_queue_end = NULL; - -static void add_to_async_queue(int taskid, - struct mm_struct *mm, - unsigned long address, - int write, - void (*callback)(int,unsigned long,int,int)) -{ - struct async_job *a = kmalloc(sizeof(*a),GFP_ATOMIC); - - if (!a) { - printk("ERROR: out of memory in asyncd\n"); - a->callback(taskid,address,write,1); - return; - } - - if (write) - stats.write++; - else - stats.read++; - - a->next = NULL; - a->taskid = taskid; - a->mm = mm; - a->address = address; - a->write = write; - a->callback = callback; - - if (!async_queue) { - async_queue = a; - } else { - async_queue_end->next = a; - } - async_queue_end = a; -} - - -void async_fault(unsigned long address, int write, int taskid, - void (*callback)(int,unsigned long,int,int)) -{ -#warning Need some fixing here... -DaveM - struct task_struct *tsk = current /* XXX task[taskid] */; - struct mm_struct *mm = tsk->mm; - - stats.faults++; - -#if 0 - printk("paging in %x for task=%d\n",address,taskid); -#endif - - add_to_async_queue(taskid, mm, address, write, callback); - wake_up(&asyncd_wait); - mark_bh(TQUEUE_BH); -} - -static int fault_in_page(int taskid, - struct vm_area_struct *vma, - unsigned long address, int write) -{ - static unsigned last_address; - static int last_task, loop_counter; - siginfo_t info; -#warning Need some fixing here... -DaveM - struct task_struct *tsk = current /* XXX task[taskid] */; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - if (!tsk || !tsk->mm) - return 1; - - if (!vma || (write && !(vma->vm_flags & VM_WRITE))) - goto bad_area; - if (vma->vm_start > address) - goto bad_area; - - if (address == last_address && taskid == last_task) { - loop_counter++; - } else { - loop_counter = 0; - last_address = address; - last_task = taskid; - } - - if (loop_counter == WRITE_LIMIT && !write) { - printk("MSC bug? setting write request\n"); - stats.errors++; - write = 1; - } - - if (loop_counter == LOOP_LIMIT) { - printk("MSC bug? failing request\n"); - stats.errors++; - return 1; - } - - pgd = pgd_offset(vma->vm_mm, address); - pmd = pmd_alloc(pgd,address); - if(!pmd) - goto no_memory; - pte = pte_alloc(pmd, address); - if(!pte) - goto no_memory; - if(!pte_present(*pte)) { - handle_mm_fault(tsk, vma, address, write); - goto finish_up; - } - set_pte(pte, pte_mkyoung(*pte)); - flush_tlb_page(vma, address); - if(!write) - goto finish_up; - if(pte_write(*pte)) { - set_pte(pte, pte_mkdirty(*pte)); - flush_tlb_page(vma, address); - goto finish_up; - } - handle_mm_fault(tsk, vma, address, write); - - /* Fall through for do_wp_page */ -finish_up: - stats.success++; - return 0; - -no_memory: - stats.failure++; - oom(tsk); - return 1; - -bad_area: - stats.failure++; - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = SEGV_MAPERR; - info.si_addr = (void *)address; - info.si_trapno = 0; - send_sig_info(SIGSEGV, &info, tsk); - return 1; -} - - -/* Note the semaphore operations must be done here, and _not_ - * in async_fault(). - */ -static void run_async_queue(void) -{ - int ret; - unsigned flags; - - while (async_queue) { - volatile struct async_job *a; - struct mm_struct *mm; - struct vm_area_struct *vma; - - save_flags(flags); cli(); - a = async_queue; - async_queue = async_queue->next; - restore_flags(flags); - - mm = a->mm; - - down(&mm->mmap_sem); - vma = find_vma(mm, a->address); - ret = fault_in_page(a->taskid,vma,a->address,a->write); -#if DEBUG - printk("fault_in_page(task=%d addr=%x write=%d) = %d\n", - a->taskid,a->address,a->write,ret); -#endif - a->callback(a->taskid,a->address,a->write,ret); - up(&mm->mmap_sem); - kfree_s((void *)a,sizeof(*a)); - } -} - - -#if CONFIG_AP1000 -static void asyncd_info(void) -{ - printk("CID(%d) faults: total=%d read=%d write=%d success=%d fail=%d err=%d\n", - mpp_cid(),stats.faults, stats.read, stats.write, stats.success, - stats.failure, stats.errors); -} -#endif - - -/* - * The background async daemon. - * Started as a kernel thread from the init process. - */ -int asyncd(void *unused) -{ - current->session = 1; - current->pgrp = 1; - sprintf(current->comm, "asyncd"); - - sigfillset(¤t->blocked); /* block all signals */ - recalc_sigpending(current); - - /* Give asyncd a realtime priority. */ - current->policy = SCHED_FIFO; - current->priority = 32; /* Fixme --- we need to standardise our - namings for POSIX.4 realtime scheduling - priorities. */ - - printk("Started asyncd\n"); - -#if CONFIG_AP1000 - bif_add_debug_key('a',asyncd_info,"stats on asyncd"); -#endif - - while (1) { - unsigned flags; - - save_flags(flags); cli(); - - while (!async_queue) { - spin_lock(¤t->sigmask_lock); - flush_signals(current); - spin_unlock(¤t->sigmask_lock); - interruptible_sleep_on(&asyncd_wait); - __sti(); cli(); /* acquire gloabl_irq_lock */ - } - - restore_flags(flags); - - run_async_queue(); - } -} - diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 450d2fc9e..46dbfb241 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.20 2000/01/12 02:59:26 davem Exp $ +/* $Id: misc.c,v 1.21 2000/01/29 07:40:15 davem Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) -- cgit v1.2.3