diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-06-01 03:16:17 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-06-01 03:16:17 +0000 |
commit | d8d9b8f76f22b7a16a83e261e64f89ee611f49df (patch) | |
tree | 3067bc130b80d52808e6390c9fc7fc087ec1e33c /arch/mips | |
parent | 19c9bba94152148523ba0f7ef7cffe3d45656b11 (diff) |
Initial revision
Diffstat (limited to 'arch/mips')
49 files changed, 744 insertions, 540 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 5ea699450..1aa371ae1 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -156,9 +156,9 @@ endif # The pipe options is bad for my low-mem machine # Uncomment this if you want this. # -#CFLAGS += -pipe +CFLAGS += -pipe -HEAD := arch/mips/kernel/head.o +HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o SUBDIRS := $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib tools) CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES) diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index fd445c865..dd834efd9 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -34,7 +34,11 @@ mkboot: mkboot.c $(HOSTCC) -o $@ $^ zdisk: zImage - mcopy -o zImage a:vmlinux + if [ -f /etc/remote-mcopy ]; then \ + ssh rio mcopy -o - a:vmlinux <zImage; \ + else \ + mcopy -o zImage a:vmlinux; \ + fi dep: $(CPP) -M *.[cS] > .depend diff --git a/arch/mips/boot/mkboot.c b/arch/mips/boot/mkboot.c index 48f27113e..35612d248 100644 --- a/arch/mips/boot/mkboot.c +++ b/arch/mips/boot/mkboot.c @@ -355,7 +355,7 @@ main(argc, argv) char *infile, *outfile; struct stat ifstat; off_t ifsize; - void *image; + char *image; int ifd, ofd, i, symtabix, strtabix; Elf32_Ehdr eh; Elf32_Phdr *ph; @@ -421,7 +421,7 @@ main(argc, argv) * we're reading might have different type sizes, byteorder * or alignment than the host. */ - memcpy(eh.e_ident, image, sizeof(eh.e_ident)); + memcpy(eh.e_ident, (void *)image, sizeof(eh.e_ident)); if(memcmp(eh.e_ident, ELFMAG, SELFMAG)) { fprintf(stderr, "Input file isn't a ELF file\n"); exit(1); @@ -476,7 +476,7 @@ main(argc, argv) exit(1); } for(i = 0;i < eh.e_phnum; i++) - get_elfph(image + eh.e_phoff + i * 32, ph + i); + get_elfph((void *)(image + eh.e_phoff + i * 32), ph + i); /* * ... and then the section headers. @@ -487,7 +487,7 @@ main(argc, argv) exit(1); } for(i = 0;i < eh.e_shnum; i++) - get_elfsh(image + eh.e_shoff + (i * 40), sh + i); + get_elfsh((void *)(image + eh.e_shoff + (i * 40)), sh + i); /* * Find the symboltable and the stringtable in the file. diff --git a/arch/mips/config.in b/arch/mips/config.in index a0e655ea1..14e9dec3f 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -178,23 +178,27 @@ fi source fs/Config.in if [ "$CONFIG_SGI" != "y" ]; then - source drivers/char/Config.in + source drivers/char/Config.in - mainmenu_option next_comment - comment 'Sound' + mainmenu_option next_comment + comment 'Sound' - tristate 'Sound card support' CONFIG_SOUND - if [ "$CONFIG_SOUND" != "n" ]; then - source drivers/sound/Config.in - fi - endmenu + tristate 'Sound card support' CONFIG_SOUND + if [ "$CONFIG_SOUND" != "n" ]; then + source drivers/sound/Config.in + fi + endmenu else - comment 'SGI Character Devices' - tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE - bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL - if [ "$CONFIG_SGI_SERIAL" != "n" ]; then - define_bool CONFIG_SERIAL y - fi + comment 'SGI Character Devices' + bool 'Virtual terminal' CONFIG_VT + if [ "$CONFIG_VT" = "y" ]; then + bool 'Console on virtual terminal' CONFIG_VT_CONSOLE + fi + tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE + bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL + if [ "$CONFIG_SGI_SERIAL" != "n" ]; then + define_bool CONFIG_SERIAL y + fi fi mainmenu_option next_comment diff --git a/arch/mips/defconfig b/arch/mips/defconfig index dc28a8cd8..33f54a301 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -22,6 +22,7 @@ CONFIG_PCI=y # # CONFIG_CPU_R3000 is not set # CONFIG_CPU_R6000 is not set +# CONFIG_CPU_R4300 is not set CONFIG_CPU_R4X00=y # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R8000 is not set diff --git a/arch/mips/deskstation/io.c b/arch/mips/deskstation/io.c new file mode 100644 index 000000000..cd33e2eb6 --- /dev/null +++ b/arch/mips/deskstation/io.c @@ -0,0 +1,68 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Low level I/O functions for Jazz family machine. + * + * FIXME: This implementation fits the Tyne. How does the EISA rPC44 handle + * the eight high address bits? + */ +#include <linux/string.h> +#include <asm/mipsconfig.h> +#include <asm/addrspace.h> +#include <asm/sni.h> + +/* + * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * for the processor. + */ +extern unsigned long isa_slot_offset; + +static unsigned char deskstation_readb(unsigned long addr) +{ + return *(volatile unsigned char *) (isa_slot_offset + addr); +} + +static unsigned short deskstation_readw(unsigned long addr) +{ + return *(volatile unsigned short *) (isa_slot_offset + addr); +} + +static unsigned int deskstation_readl(unsigned long addr) +{ + return *(volatile unsigned int *) (isa_slot_offset + addr); +} + +static void deskstation_writeb(unsigned char val, unsigned long addr) +{ + *(volatile unsigned char *) (isa_slot_offset + addr) = val; +} + +static void deskstation_writew(unsigned short val, unsigned long addr) +{ + *(volatile unsigned char *) (isa_slot_offset + addr) = val; +} + +static void deskstation_writel(unsigned int val, unsigned long addr) +{ + *(volatile unsigned char *) (isa_slot_offset + addr) = val; +} + +static void deskstation_memset_io(unsigned long addr, int val, unsigned long len) +{ + addr += isa_slot_offset; + memset((void *)addr, val, len); +} + +static void deskstation_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len) +{ + from += isa_slot_offset; + memcpy((void *)to, (void *)from, len); +} + +static void deskstation_memcpy_toio(unsigned long to, unsigned long from, unsigned long len) +{ + to += isa_slot_offset; + memcpy((void *)to, (void *)from, len); +} diff --git a/arch/mips/deskstation/setup.c b/arch/mips/deskstation/setup.c index c2451e855..8b70a656c 100644 --- a/arch/mips/deskstation/setup.c +++ b/arch/mips/deskstation/setup.c @@ -5,10 +5,10 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 1997 by Ralf Baechle */ -#include <asm/ptrace.h> #include <linux/config.h> +#include <linux/init.h> #include <linux/ioport.h> #include <linux/sched.h> #include <linux/interrupt.h> @@ -16,6 +16,7 @@ #include <asm/bootinfo.h> #include <asm/io.h> #include <asm/irq.h> +#include <asm/ptrace.h> #include <asm/mipsregs.h> #include <asm/reboot.h> #include <asm/vector.h> @@ -43,8 +44,7 @@ extern void deskstation_machine_power_off(void); unsigned long mips_dma_cache_size = 0; unsigned long mips_dma_cache_base = KSEG0; -static void -tyne_irq_setup(void) +__initfunc(static void tyne_irq_setup(void)) { set_except_vector(0, deskstation_handle_int); /* set the clock to 100 Hz */ @@ -58,8 +58,7 @@ tyne_irq_setup(void) #endif #ifdef CONFIG_DESKSTATION_RPC44 -static void -rpc44_irq_setup(void) +__initfunc(static void rpc44_irq_setup(void)) { /* * For the moment just steal the TYNE support. In the @@ -77,8 +76,7 @@ rpc44_irq_setup(void) } #endif -void -deskstation_setup(void) +__initfunc(void deskstation_setup(void)) { switch(mips_machtype) { #ifdef CONFIG_DESKSTATION_TYNE diff --git a/arch/mips/jazz/.cvsignore b/arch/mips/jazz/.cvsignore new file mode 100644 index 000000000..4671378ae --- /dev/null +++ b/arch/mips/jazz/.cvsignore @@ -0,0 +1 @@ +.depend diff --git a/arch/mips/jazz/io.c b/arch/mips/jazz/io.c new file mode 100644 index 000000000..a151b99fe --- /dev/null +++ b/arch/mips/jazz/io.c @@ -0,0 +1,136 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Low level I/O functions for Jazz family machines. + * + * Copyright (C) 1997 by Ralf Baechle. + */ +#include <linux/string.h> +#include <asm/mipsconfig.h> +#include <asm/addrspace.h> +#include <asm/system.h> +#include <asm/spinlock.h> +#include <asm/jazz.h> + +/* + * Map an 16mb segment of the EISA address space to 0xe3000000; + */ +static inline void map_eisa_address(unsigned long address) +{ + /* XXX */ + /* We've got an wired entry in the TLB. We just need to modify it. + fast and clean. But since we want to get rid of wired entries + things are a little bit more complicated ... */ +} + +static unsigned char jazz_readb(unsigned long addr) +{ + unsigned char res; + + map_eisa_address(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (JAZZ_EISA_BASE + addr); + + return res; +} + +static unsigned short jazz_readw(unsigned long addr) +{ + unsigned short res; + + map_eisa_address(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (JAZZ_EISA_BASE + addr); + + return res; +} + +static unsigned int jazz_readl(unsigned long addr) +{ + unsigned int res; + + map_eisa_address(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (JAZZ_EISA_BASE + addr); + + return res; +} + +static void jazz_writeb(unsigned char val, unsigned long addr) +{ + map_eisa_address(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (JAZZ_EISA_BASE + addr) = val; +} + +static void jazz_writew(unsigned short val, unsigned long addr) +{ + map_eisa_address(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (JAZZ_EISA_BASE + addr) = val; +} + +static void jazz_writel(unsigned int val, unsigned long addr) +{ + map_eisa_address(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (JAZZ_EISA_BASE + addr) = val; +} + +static void jazz_memset_io(unsigned long addr, int val, unsigned long len) +{ + unsigned long waddr; + + waddr = JAZZ_EISA_BASE | (addr & 0xffffff); + while(len) { + unsigned long fraglen; + + fraglen = (~addr + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + map_eisa_address(addr); + memset((char *)waddr, val, fraglen); + addr += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } +} + +static void jazz_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len) +{ + unsigned long waddr; + + waddr = JAZZ_EISA_BASE | (from & 0xffffff); + while(len) { + unsigned long fraglen; + + fraglen = (~from + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + map_eisa_address(from); + memcpy((void *)to, (void *)waddr, fraglen); + to += fraglen; + from += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } +} + +static void jazz_memcpy_toio(unsigned long to, unsigned long from, unsigned long len) +{ + unsigned long waddr; + + waddr = JAZZ_EISA_BASE | (to & 0xffffff); + while(len) { + unsigned long fraglen; + + fraglen = (~to + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + map_eisa_address(to); + memcpy((char *)to + JAZZ_EISA_BASE, (void *)from, fraglen); + to += fraglen; + from += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } +} diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index 1b137cf85..805efa821 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -5,14 +5,15 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 1997 by Ralf Baechle */ -#include <asm/ptrace.h> +#include <linux/init.h> #include <linux/ioport.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <asm/irq.h> #include <asm/jazz.h> +#include <asm/ptrace.h> #include <asm/reboot.h> #include <asm/vector.h> #include <asm/io.h> @@ -35,8 +36,7 @@ extern void jazz_machine_restart(char *command); extern void jazz_machine_halt(void); extern void jazz_machine_power_off(void); -static void -jazz_irq_setup(void) +__initfunc(static void jazz_irq_setup(void)) { set_except_vector(0, jazz_handle_int); r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, @@ -55,8 +55,7 @@ jazz_irq_setup(void) setup_x86_irq(2, &irq2); } -void -jazz_setup(void) +__initfunc(void jazz_setup(void)) { irq_setup = jazz_irq_setup; fd_cacheflush = jazz_fd_cacheflush; diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index b251d6e1a..21dd3610b 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -9,7 +9,7 @@ .S.o: $(CC) $(CFLAGS) -c $< -o $*.o -all: kernel.o head.o +all: kernel.o head.o init_task.o EXTRA_ASFLAGS = -mips3 -mcpu=r4000 O_TARGET := kernel.o O_OBJS := branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \ diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 8bb8fb41c..682e00cda 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -14,9 +14,11 @@ * and faults that can result in a task-switch. The ISA dependent TLB * code is in arch/mips/<ISA-level>/<cputype>.S */ +#include <linux/config.h> #include <linux/sys.h> #include <asm/asm.h> +#include <asm/current.h> #include <asm/errno.h> #include <asm/mipsregs.h> #include <asm/mipsconfig.h> @@ -53,7 +55,6 @@ reschedule: nop EXPORT(ret_from_sys_call) - lw t0,bh_mask lw t1,bh_active # unused delay slot and t0,t1 @@ -64,7 +65,7 @@ EXPORT(ret_from_sys_call) beqz t1,return # -> yes lw t1,need_resched bnez t1,reschedule - lw s0,current_set + GET_CURRENT(s0) lw t0,task lw a0,TASK_BLOCKED(s0) diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index a957e16bd..4c3e5bd52 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -22,6 +22,15 @@ #include <asm/bootinfo.h> #include <asm/cpu.h> +/* + * Get current task pointer + */ +#define GET_CURRENT(reg) \ + lui reg, %hi(kernelsp); \ + lw reg, %lo(kernelsp)(reg); \ + ori reg, 8191; \ + xori reg, 8191 + .text /* * Reserved space for exception handlers. @@ -43,8 +52,7 @@ LEAF(except_vec0_r4000) .set mips3 mfc0 k0, CP0_BADVADDR # Get faulting address - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) # get current task ptr + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 # get pgd only bits lw k1, THREAD_PGDIR(k1) # get task pg_dir sll k0, k0, 2 @@ -71,8 +79,7 @@ LEAF(except_vec0_r4600) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -98,8 +105,7 @@ LEAF(except_vec0_r45k_bvahwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -129,8 +135,7 @@ LEAF(except_vec0_r4k_mphwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -160,8 +165,7 @@ LEAF(except_vec0_r4k_250MHZhwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -191,8 +195,7 @@ LEAF(except_vec0_r4k_MP250MHZhwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -224,8 +227,7 @@ LEAF(except_vec0_r2300) .set mips1 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -403,9 +405,11 @@ probe_done: /* * Stack for kernel and init + * + * Kernelsp will never be referenced for process 0. */ -9: la sp, init_user_stack+(KERNEL_STACK_SIZE-4*SZREG) - la t0, init_kernel_stack+(KERNEL_STACK_SIZE) +9: la sp, init_task_union+(KERNEL_STACK_SIZE-4*SZREG) + la t0, init_task_union+(KERNEL_STACK_SIZE) sw t0, kernelsp /* Disable coprocessors */ @@ -745,9 +749,13 @@ map0_sni_rm200_pci: .org 0x6000 + /* + * init_task_union follows here in the .text segment. + * Keep this aligned to a 8kb boundary! + */ + .data EXPORT(cache_error_buffer) .fill 32*4,1,0 - .data EXPORT(kernelsp) PTR 0 diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c new file mode 100644 index 000000000..cc0a19231 --- /dev/null +++ b/arch/mips/kernel/init_task.c @@ -0,0 +1,22 @@ +#include <linux/mm.h> +#include <linux/sched.h> + +#include <asm/pgtable.h> + +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; +struct mm_struct init_mm = INIT_MM; + +/* + * Initial task structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union task_union init_task_union __attribute__((__section__(".text"))) = { INIT_TASK }; diff --git a/arch/mips/kernel/irix5sys.h b/arch/mips/kernel/irix5sys.h index a20e619e3..be57dc1f5 100644 --- a/arch/mips/kernel/irix5sys.h +++ b/arch/mips/kernel/irix5sys.h @@ -105,7 +105,7 @@ SYS(irix_sgikopt, 3) /* 1083 sys_sgikopt() DC*/ SYS(sys_sysfs, 3) /* 1084 sysfs() ?V*/ SYS(irix_unimp, 0) /* 1085 XXX sys_getmsg() DC*/ SYS(irix_unimp, 0) /* 1086 XXX sys_putmsg() DC*/ -SYS(irix_poll, 3) /* 1087 sys_poll() V*/ +SYS(sys_poll, 3) /* 1087 poll() V*/ SYS(irix_sigreturn, 0) /* 1088 sigreturn() ?V*/ SYS(sys_accept, 3) /* 1089 accept() V*/ SYS(sys_bind, 3) /* 1090 bind() V*/ diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 46345b308..d994155d0 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1,4 +1,4 @@ -/* $Id: irixelf.c,v 1.8 1996/08/24 03:52:25 dm Exp $ +/* * irixelf.c: Code to load IRIX ELF executables which conform to * the MIPS ABI. * @@ -17,6 +17,7 @@ #include <linux/mman.h> #include <linux/a.out.h> #include <linux/errno.h> +#include <linux/init.h> #include <linux/signal.h> #include <linux/binfmts.h> #include <linux/string.h> @@ -720,16 +721,16 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, sys_close(elf_exec_fileno); current->personality = PER_IRIX32; - if (current->exec_domain && current->exec_domain->use_count) - (*current->exec_domain->use_count)--; - if (current->binfmt && current->binfmt->use_count) - (*current->binfmt->use_count)--; + if (current->exec_domain && current->exec_domain->module) + __MOD_DEC_USE_COUNT(current->exec_domain->module); + if (current->binfmt && current->binfmt->module) + __MOD_DEC_USE_COUNT(current->binfmt->module); current->exec_domain = lookup_exec_domain(current->personality); current->binfmt = &irix_format; - if (current->exec_domain && current->exec_domain->use_count) - (*current->exec_domain->use_count)++; - if (current->binfmt && current->binfmt->use_count) - (*current->binfmt->use_count)++; + if (current->exec_domain && current->exec_domain->module) + __MOD_INC_USE_COUNT(current->exec_domain->module); + if (current->binfmt && current->binfmt->module) + __MOD_INC_USE_COUNT(current->binfmt->module); current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; @@ -1180,20 +1181,20 @@ static int irix_core_dump(long signr, struct pt_regs * regs) notes[0].datasz = sizeof(prstatus); notes[0].data = &prstatus; prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; - copy_sigbits32(&prstatus.pr_sigpend, current->signal); - copy_sigbits32(&prstatus.pr_sighold, current->blocked); + prstatus.pr_sigpend = current->signal; + prstatus.pr_sighold = current->blocked; psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp; psinfo.pr_sid = prstatus.pr_sid = current->session; - prstatus.pr_utime.tv_sec = CT_TO_SECS(current->utime); - prstatus.pr_utime.tv_usec = CT_TO_USECS(current->utime); - prstatus.pr_stime.tv_sec = CT_TO_SECS(current->stime); - prstatus.pr_stime.tv_usec = CT_TO_USECS(current->stime); - prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->cutime); - prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->cutime); - prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->cstime); - prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->cstime); + prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime); + prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime); + prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime); + prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime); + prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime); + prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime); + prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime); + prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime); if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) " "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); @@ -1339,13 +1340,15 @@ static int irix_core_dump(long signr, struct pt_regs * regs) return has_dumped; } -int init_irix_binfmt(void) { +__initfunc(int init_irix_binfmt(void)) +{ return register_binfmt(&irix_format); } #ifdef MODULE -int init_module(void) { +int init_module(void) +{ /* Install the COFF, ELF and XOUT loaders. * N.B. We *rely* on the table being the right size with the * right number of free slots... @@ -1354,7 +1357,8 @@ int init_module(void) { } -void cleanup_module( void) { +void cleanup_module( void) +{ /* Remove the IRIX ELF loaders. */ unregister_binfmt(&irix_format); } diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c index 3405904fa..e0230f9f0 100644 --- a/arch/mips/kernel/irixioctl.c +++ b/arch/mips/kernel/irixioctl.c @@ -8,6 +8,8 @@ #include <linux/sched.h> #include <linux/fs.h> #include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/tty.h> #include <asm/uaccess.h> diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index 6a5636c76..b2d7cbe49 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -8,6 +8,8 @@ #include <linux/sched.h> #include <linux/mm.h> #include <linux/errno.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/time.h> #include <asm/ptrace.h> @@ -162,7 +164,10 @@ asmlinkage int do_irix_signal(unsigned long oldmask, struct pt_regs * regs) case SIGCONT: case SIGCHLD: case SIGWINCH: continue; - case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + case SIGSTOP: if (current->flags & PF_PTRACED) continue; current->state = TASK_STOPPED; @@ -175,15 +180,19 @@ asmlinkage int do_irix_signal(unsigned long oldmask, struct pt_regs * regs) case SIGQUIT: case SIGILL: case SIGTRAP: case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS: + lock_kernel(); if (current->binfmt && current->binfmt->core_dump) { if (current->binfmt->core_dump(signr, regs)) signr |= 0x80; } + unlock_kernel(); /* fall through */ default: current->signal |= _S(signr & 0x7f); current->flags |= PF_SIGNALED; + lock_kernel(); /* 8-( */ do_exit(signr); + unlock_kernel(); } } /* @@ -314,7 +323,7 @@ static inline void check_pending(int signum) spin_lock(¤t->sigmask_lock); if (p->sa_handler == SIG_IGN) { current->signal &= ~_S(signum); - } else if if (p->sa_handler == SIG_DFL) { + } else if (p->sa_handler == SIG_DFL) { if (signum != SIGCONT && signum != SIGCHLD && signum != SIGWINCH) return; current->signal &= ~_S(signum); @@ -347,11 +356,9 @@ asmlinkage int irix_sigaction(int sig, struct sigact_irix5 *new, if(sig == SIGKILL || sig == SIGSTOP) { return -EINVAL; } - new_sa.sa_flags = new->flags; - new_sa.sa_handler = (__sighandler_t) new->handler; - new_sa.sa_mask.__sigbits[1] = new_sa.sa_mask.__sigbits[2] = - new_sa.sa_mask.__sigbits[3] = 0; - new_sa.sa_mask.__sigbits[0] = new->sigset[0]; + __get_user(new_sa.sa_flags, &new->flags); + __get_user(new_sa.sa_handler, &(__sighandler_t) new->handler); + __get_user(new_sa.sa_mask, &new->sigset[0]); if(new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) { res = verify_area(VERIFY_READ, new_sa.sa_handler, 1); @@ -368,19 +375,22 @@ asmlinkage int irix_sigaction(int sig, struct sigact_irix5 *new, int res = verify_area(VERIFY_WRITE, old, sizeof(*old)); if(res) return res; - old->flags = p->sa_flags; - old->handler = (void *) p->sa_handler; - old->sigset[1] = old->sigset[2] = old->sigset[3] = 0; - old->sigset[0] = p->sa_mask.__sigbits[0]; - old->_unused0[0] = old->_unused0[1] = 0; + __put_user(p->sa_flags, &old->flags); + __put_user(p->sa_handler, &old->handler); + __put_user(p->sa_mask, &old->sigset[0]); + __put_user(0, &old->sigset[1]); + __put_user(0, &old->sigset[2]); + __put_user(0, &old->sigset[3]); + __put_user(0, &old->_unused0[0]); + __put_user(0, &old->_unused0[1]); } - if(new) { spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(sig); spin_unlock_irq(¤t->sig->siglock); } + return 0; } @@ -640,14 +650,14 @@ repeat: __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); - __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); + __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); + __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); p->exit_code = 0; retval = 0; goto end_waitsys; case TASK_ZOMBIE: - current->cutime += p->utime + p->cutime; - current->cstime += p->stime + p->cstime; + current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; + current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); __put_user(SIGCHLD, &info->sig); @@ -655,9 +665,9 @@ repeat: __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); - __put_user(p->utime, + __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->stime, + __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); retval = 0; if (p->p_opptr != p->p_pptr) { @@ -855,6 +865,8 @@ asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new, out: error = 0; unlock_kernel(); + + return error; } struct irix_procset { diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index a78bc3417..0896ed1c7 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -13,6 +13,7 @@ */ #include <linux/config.h> #include <linux/errno.h> +#include <linux/init.h> #include <linux/kernel_stat.h> #include <linux/signal.h> #include <linux/sched.h> @@ -154,11 +155,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) irq_enter(cpu, irq); kstat.interrupts[irq]++; -#ifdef CONFIG_SGI - prom_printf("Got irq %d, press a key.", irq); - prom_getchar(); - romvec->imode(); -#endif /* slow interrupts run with interrupts enabled */ sti(); action = *(irq + irq_action); @@ -344,7 +340,7 @@ int probe_irq_off (unsigned long irqs) return i; } -void init_IRQ(void) +__initfunc(void init_IRQ(void)) { int i; diff --git a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c index e521ecdd9..5e71233af 100644 --- a/arch/mips/kernel/pci.c +++ b/arch/mips/kernel/pci.c @@ -7,6 +7,7 @@ */ #include <linux/bios32.h> #include <linux/config.h> +#include <linux/init.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/types.h> @@ -17,7 +18,8 @@ /* * BIOS32 replacement. */ -unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end) +__initfunc(unsigned long pcibios_init(unsigned long memory_start, + unsigned long memory_end)) { return memory_start; } @@ -112,7 +114,8 @@ const char *pcibios_strerror (int error) * specific implementation. */ unsigned long (*_pcibios_init)(unsigned long memory_start, unsigned long memory_end); -unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end) +__initfunc(unsigned long pcibios_init(unsigned long memory_start, + unsigned long memory_end)) { return _pcibios_init ? _pcibios_init(memory_start, memory_end) : memory_start; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f8b10bdea..08dd13c6c 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -64,16 +64,23 @@ void release_thread(struct task_struct *dead_task) { } +#define roundup(val, rnd) ({ \ + unsigned _v = val; \ + unsigned long _r = rnd; \ + _v = (_v + _r - 1) & ~(_r - 1); \ + _v; \ +}) + int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; long childksp; - childksp = p->kernel_stack_page + KERNEL_STACK_SIZE - 8; + childksp = roundup((unsigned long)p, KERNEL_STACK_SIZE) - 8; /* set up new TSS. */ - childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; + childregs = ((struct pt_regs *) ((unsigned long)p + KERNEL_STACK_SIZE)) - 1; *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ if(current->personality == PER_LINUX) { diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 41deb8f18..e61911549 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -18,18 +18,6 @@ #include <asm/page.h> #include <asm/system.h> -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * This routine gets a long from any process space by following the page * tables. NOTE! You should check that the long isn't on a page boundary, @@ -47,7 +35,7 @@ static unsigned long get_long(struct task_struct * tsk, repeat: pgdir = pgd_offset(vma->vm_mm, addr); if (pgd_none(*pgdir)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } if (pgd_bad(*pgdir)) { @@ -57,7 +45,7 @@ repeat: } pgmiddle = pmd_offset(pgdir, addr); if (pmd_none(*pgmiddle)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } if (pmd_bad(*pgmiddle)) { @@ -67,7 +55,7 @@ repeat: } pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } page = pte_page(*pgtable); @@ -101,7 +89,7 @@ static void put_long(struct task_struct *tsk, repeat: pgdir = pgd_offset(vma->vm_mm, addr); if (!pgd_present(*pgdir)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } if (pgd_bad(*pgdir)) { @@ -111,7 +99,7 @@ repeat: } pgmiddle = pmd_offset(pgdir, addr); if (pmd_none(*pgmiddle)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } if (pmd_bad(*pgmiddle)) { @@ -121,12 +109,12 @@ repeat: } pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } page = pte_page(*pgtable); if (!pte_write(*pgtable)) { - do_wp_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } /* this is a hack for non-kernel-mapped video buffers and similar */ @@ -280,7 +268,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) res = -EPERM; goto out; } - if (!(child = get_task(pid))) { + if (!(child = find_task_by_pid(pid))) { res = -ESRCH; goto out; } diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 83190514b..901871a31 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -9,6 +9,7 @@ #include <asm/asm.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> @@ -31,8 +32,7 @@ MODE_ALIAS = 0x00e0 # uncachable, dirty, valid */ .align 5 LEAF(r2300_resume) - lui t5, %hi(current_set) - lw t0, %lo(current_set)(t5) + GET_CURRENT(t0) mfc0 t1,CP0_STATUS # Save status register addu t0,a1 # Add tss offset sw t1,THREAD_STATUS(t0) @@ -50,7 +50,6 @@ MODE_ALIAS = 0x00e0 # uncachable, dirty, valid 1: FPU_SAVE_16EVEN(t0, t1) 2: - sw a0,%lo(current_set)(t5) # Switch current task addu a0,a1 # Add tss offset lw t0,THREAD_PGDIR(a0) # Switch the root pointer li t1,TLB_ROOT # get PFN diff --git a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S index 432c65215..5c9ad4d84 100644 --- a/arch/mips/kernel/r4k_misc.S +++ b/arch/mips/kernel/r4k_misc.S @@ -10,6 +10,7 @@ #include <asm/offset.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> @@ -29,9 +30,8 @@ */ #define LOAD_PTE(pte, ptr) \ mfc0 pte, CP0_BADVADDR; \ - lui ptr, %hi(current_set); \ srl pte, pte, 22; \ - lw ptr, %lo(current_set)(ptr); \ + GET_CURRENT(ptr); \ sll pte, pte, 2; \ lw ptr, THREAD_PGDIR(ptr); \ addu ptr, pte, ptr; \ diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 78ced5659..97e253028 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -1,4 +1,4 @@ -/* $Id: r4k_switch.S,v 1.8 1996/07/10 01:24:20 dm Exp $ +/* * r4k_switch.S: R4xx0 specific task switching code. * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse @@ -9,6 +9,7 @@ #include <asm/asm.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> @@ -24,8 +25,7 @@ .set mips3 .align 5 LEAF(r4xx0_resume) - lui t5, %hi(current_set) - lw t0, %lo(current_set)(t5) + GET_CURRENT(t0) mfc0 t1, CP0_STATUS nop sw t1, THREAD_STATUS(t0) @@ -43,7 +43,6 @@ 1: FPU_SAVE_16EVEN(t0, t1) # clobbers t1 2: - sw a0, %lo(current_set)(t5) lw a3, TASK_MM(a0) lw a2, THREAD_STATUS(a0) lw a3, MM_CONTEXT(a3) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 2e2b074f9..7616fa7c6 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -7,6 +7,7 @@ */ #include <linux/config.h> #include <linux/errno.h> +#include <linux/init.h> #include <linux/ioport.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -123,17 +124,17 @@ void (*irq_setup)(void); */ unsigned long isa_slot_offset; -static void default_irq_setup(void) +__initfunc(static void default_irq_setup(void)) { panic("Unknown machtype in init_IRQ"); } -static void default_fd_cacheflush(const void *addr, size_t size) +__initfunc(static void default_fd_cacheflush(const void *addr, size_t size)) { } -void setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p) +__initfunc(void setup_arch(char **cmdline_p, + unsigned long * memory_start_p, unsigned long * memory_end_p)) { unsigned long memory_end; tag* atag; diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 848f0742b..304dc6418 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -307,7 +307,10 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) case SIGCONT: case SIGCHLD: case SIGWINCH: continue; - case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + case SIGSTOP: if (current->flags & PF_PTRACED) continue; current->state = TASK_STOPPED; @@ -318,11 +321,15 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) schedule(); continue; - case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS: + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: + lock_kernel(); if (current->binfmt && current->binfmt->core_dump) { if (current->binfmt->core_dump(signr, regs)) signr |= 0x80; } + unlock_kernel(); /* fall through */ default: spin_lock_irq(¤t->sigmask_lock); diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index 4cf778acb..6c7d3988c 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -174,6 +174,7 @@ SYS(sys_mlock, 2) SYS(sys_munlock, 2) /* 4155 */ SYS(sys_mlockall, 1) SYS(sys_munlockall, 0) +SYS(sys_nfsservctl, 3) SYS(sys_sched_setparam,2) SYS(sys_sched_getparam,2) SYS(sys_sched_setscheduler,3) /* 4160 */ diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 9a4ddca3f..7917664fd 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -17,6 +17,8 @@ #include <linux/elf.h> #include <linux/msg.h> #include <linux/shm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/utsname.h> #include <asm/ptrace.h> @@ -24,26 +26,7 @@ #include <asm/pgtable.h> #include <asm/uaccess.h> -/* 2,000 lines of complete and utter shit coming up... */ - -/* Utility routines. */ -static inline struct task_struct *find_process_by_pid(pid_t pid) -{ - struct task_struct *p, *q; - - if (pid == 0) - p = current; - else { - p = 0; - for_each_task(q) { - if (q && q->pid == pid) { - p = q; - break; - } - } - } - return p; -} +/* 2,300 lines of complete and utter shit coming up... */ /* The sysmp commands supported thus far. */ #define MP_PGSIZE 14 /* Return system page size in v1. */ @@ -70,7 +53,6 @@ asmlinkage int irix_sysmp(struct pt_regs *regs) break; } -out: unlock_kernel(); return error; } @@ -114,7 +96,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs) printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", current->comm, current->pid); - task = find_process_by_pid(regs->regs[base + 5]); + task = find_task_by_pid(regs->regs[base + 5]); if(!task) { error = -ESRCH; break; @@ -233,7 +215,6 @@ asmlinkage int irix_prctl(struct pt_regs *regs) break; } -out: unlock_kernel(); return error; } @@ -658,7 +639,6 @@ asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags, dev_name, dir_name, flags, type, data, datalen); ret = sys_mount(dev_name, dir_name, type, flags, data); -out: unlock_kernel(); return ret; } @@ -781,22 +761,23 @@ asmlinkage int irix_setpgrp(int flags) printk("returning %d\n", current->pgrp); #endif -out: unlock_kernel(); return error; } asmlinkage int irix_times(struct tms * tbuf) { + int error; + lock_kernel(); if (tbuf) { - int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf); + error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf); if (error) goto out; - __put_user(current->utime,&tbuf->tms_utime); - __put_user(current->stime,&tbuf->tms_stime); - __put_user(current->cutime,&tbuf->tms_cutime); - __put_user(current->cstime,&tbuf->tms_cstime); + __put_user(current->times.tms_utime,&tbuf->tms_utime); + __put_user(current->times.tms_stime,&tbuf->tms_stime); + __put_user(current->times.tms_cutime,&tbuf->tms_cutime); + __put_user(current->times.tms_cstime,&tbuf->tms_cstime); } error = 0; @@ -845,169 +826,6 @@ out: return error; } -/* sys_poll() support... */ -#define POLL_ROUND_UP(x,y) (((x)+(y)-1)/(y)) - -#define POLLIN 1 -#define POLLPRI 2 -#define POLLOUT 4 -#define POLLERR 8 -#define POLLHUP 16 -#define POLLNVAL 32 -#define POLLRDNORM 64 -#define POLLWRNORM POLLOUT -#define POLLRDBAND 128 -#define POLLWRBAND 256 - -#define LINUX_POLLIN (POLLRDNORM | POLLRDBAND | POLLIN) -#define LINUX_POLLOUT (POLLWRBAND | POLLWRNORM | POLLOUT) -#define LINUX_POLLERR (POLLERR) - -static inline void free_wait(select_table * p) -{ - struct select_table_entry * entry = p->entry + p->nr; - - while (p->nr > 0) { - p->nr--; - entry--; - remove_wait_queue(entry->wait_address,&entry->wait); - } -} - - -/* Copied directly from fs/select.c */ -static int check(int flag, select_table * wait, struct file * file) -{ - struct inode * inode; - struct file_operations *fops; - int (*select) (struct inode *, struct file *, int, select_table *); - - inode = file->f_inode; - if ((fops = file->f_op) && (select = fops->select)) - return select(inode, file, flag, wait) - || (wait && select(inode, file, flag, NULL)); - if (S_ISREG(inode->i_mode)) - return 1; - return 0; -} - -struct poll { - int fd; - short events; - short revents; -}; - -int irix_poll(struct poll * ufds, size_t nfds, int timeout) -{ - int i,j, count, fdcount, error, retflag; - struct poll * fdpnt; - struct poll * fds, *fds1; - select_table wait_table, *wait; - struct select_table_entry *entry; - - lock_kernel(); - if ((error = verify_area(VERIFY_READ, ufds, nfds*sizeof(struct poll)))) - goto out; - - if (nfds > NR_OPEN) { - error = -EINVAL; - goto out; - } - - if (!(entry = (struct select_table_entry*)__get_free_page(GFP_KERNEL)) - || !(fds = (struct poll *)kmalloc(nfds*sizeof(struct poll), GFP_KERNEL))) { - error = -ENOMEM; - goto out; - } - - copy_from_user(fds, ufds, nfds*sizeof(struct poll)); - - if (timeout < 0) - current->timeout = 0x7fffffff; - else { - current->timeout = jiffies + POLL_ROUND_UP(timeout, (1000/HZ)); - if (current->timeout <= jiffies) - current->timeout = 0; - } - - count = 0; - wait_table.nr = 0; - wait_table.entry = entry; - wait = &wait_table; - - for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) { - i = fdpnt->fd; - fdpnt->revents = 0; - if (!current->files->fd[i] || !current->files->fd[i]->f_inode) - fdpnt->revents = POLLNVAL; - } -repeat: - current->state = TASK_INTERRUPTIBLE; - for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) { - i = fdpnt->fd; - - if(i < 0) continue; - if (!current->files->fd[i] || !current->files->fd[i]->f_inode) continue; - - if ((fdpnt->events & LINUX_POLLIN) - && check(SEL_IN, wait, current->files->fd[i])) { - retflag = 0; - if (fdpnt->events & POLLIN) - retflag = POLLIN; - if (fdpnt->events & POLLRDNORM) - retflag = POLLRDNORM; - fdpnt->revents |= retflag; - count++; - wait = NULL; - } - - if ((fdpnt->events & LINUX_POLLOUT) && - check(SEL_OUT, wait, current->files->fd[i])) { - fdpnt->revents |= (LINUX_POLLOUT & fdpnt->events); - count++; - wait = NULL; - } - - if (check(SEL_EX, wait, current->files->fd[i])) { - fdpnt->revents |= POLLHUP; - count++; - wait = NULL; - } - } - - if ((current->signal & (~current->blocked))) { - error = -EINTR; - goto out; - } - - wait = NULL; - if (!count && current->timeout > jiffies) { - schedule(); - goto repeat; - } - - free_wait(&wait_table); - free_page((unsigned long) entry); - - /* OK, now copy the revents fields back to user space. */ - fds1 = fds; - fdcount = 0; - for(i=0; i < (int)nfds; i++, ufds++, fds++) { - if (fds->revents) { - fdcount++; - } - put_user(fds->revents, &ufds->revents); - } - kfree(fds1); - current->timeout = 0; - current->state = TASK_RUNNING; - error = fdcount; - -out: - unlock_kernel(); - return error; -} - asmlinkage unsigned long irix_gethostid(void) { lock_kernel(); @@ -1263,7 +1081,6 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp) printk("error = %d\n", error); #endif -out: unlock_kernel(); return error; } @@ -1443,11 +1260,11 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) if(error) goto out; error = irix_xstat32_xlate(&kb, statbuf); - goto error; + goto out; } case 3: { - sys_newlstat(filename, statbuf); + error = sys_newlstat(filename, statbuf); #ifdef DEBUG_XSTAT printk("error[%d]\n", error); #endif @@ -1456,7 +1273,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) irix_xstat64_xlate(statbuf); error = 0; - goto error; + goto out; } default: @@ -1466,7 +1283,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) out: unlock_kernel(); - return errno; + return error; } extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf); @@ -2018,13 +1835,13 @@ out: asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf) { - int errno; + int error; lock_kernel(); printk("[%s:%d] irix_getmountid(%s, %p)\n", current->comm, current->pid, fname, midbuf); - errno = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)); - if(errno) + error = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)); + if(error) goto out; /* @@ -2142,7 +1959,7 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count buf.error = 0; error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir32); if (error < 0) - goto out + goto out; lastdirent = buf.previous; if (!lastdirent) { error = buf.error; @@ -2431,6 +2248,8 @@ asmlinkage int irix_fcntl(int fd, int cmd, int arg) asmlinkage int irix_ulimit(int cmd, int arg) { + int retval; + lock_kernel(); switch(cmd) { case 1: diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index aa4547456..fd57f6d0e 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -7,6 +7,7 @@ * found in some MIPS systems. */ #include <linux/errno.h> +#include <linux/init.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/param.h> @@ -299,7 +300,7 @@ static struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL}; void (*board_time_init)(struct irqaction *irq); -void time_init(void) +__initfunc(void time_init(void)) { unsigned int year, mon, day, hour, min, sec; int i; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 17b1f9a28..cdbcacb43 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -17,6 +17,7 @@ * Modified for R3000 by Paul M. Antoine, 1995, 1996 */ #include <linux/config.h> +#include <linux/init.h> #include <linux/mm.h> #include <linux/smp.h> #include <linux/smp_lock.h> @@ -110,10 +111,8 @@ void show_registers(char * str, struct pt_regs * regs, long err) /* * Dump the stack */ - if (STACK_MAGIC != *(u32 *)current->kernel_stack_page) - printk("Corrupted stack page\n"); printk("Process %s (pid: %d, stackpage=%08lx)\nStack: ", - current->comm, current->pid, current->kernel_stack_page); + current->comm, current->pid, (unsigned long)current); for(i=0;i<5;i++) printk("%08x ", *sp++); stack = (int *) sp; @@ -389,7 +388,7 @@ void do_reserved(struct pt_regs *regs) unlock_kernel(); } -static void watch_init(unsigned long cputype) +static inline void watch_init(unsigned long cputype) { switch(cputype) { case CPU_R10000: @@ -427,7 +426,7 @@ extern asmlinkage void r6000_restore_fp_context(struct sigcontext *sc); extern asmlinkage void r4xx0_resume(void *tsk); extern asmlinkage void r2300_resume(void *tsk); -void trap_init(void) +__initfunc(void trap_init(void)) { extern char except_vec0_r4000, except_vec0_r4600, except_vec0_r2300; extern char except_vec1_generic, except_vec2_generic; diff --git a/arch/mips/mips/Makefile b/arch/mips/mips/Makefile new file mode 100644 index 000000000..b252e2fe4 --- /dev/null +++ b/arch/mips/mips/Makefile @@ -0,0 +1,39 @@ +# +# PROM Entries for the big endian firmware used in the Mips Computer +# System, Inc. machines. Beware: some of the machines seem to be +# different. +# +# Copyright (C) 1997 Ralf Baechle +# +prom-entries= reset exec restart reinit reboot autoboot open read write ioctl \ + close getchar putchar showchar gets puts printf initproto protoenable \ + protodisable getpkt putpkt orw_rmw orh_rmw orb_rmw andw_rmw andh_rmw \ + andb_rmw flushcache clearcache setjmp longjmp bevutlb getenv setenv \ + atob strcmp strlen strcpy strcat parser range argvize help dumpcmd \ + setenvcmd unsetenvcmd printenvcmd bevexcept enablecmd disablecmd \ + clearnofault notimplement nv_get nv_set +asm-files=$(addsuffix .S,$(prom-entries)) +object-files=$(addsuffix .o,$(prom-entries)) + +CC=mipsel-linux-gcc +AR=mipsel-linux-ar +CFLAGS=-O2 -mno-abicalls -fno-pic -G0 -Wall + +all: libprom.a + +libprom.a: $(asm-files) + set -e;for i in $(prom-entries); do \ + $(CC) $(CFLAGS) -c -o $$i.o $$i.S; \ + $(AR) rcv libprom.a $$i.o; \ + done + +$(asm-files): mkprom + set -e;for i in $(prom-entries); do \ + mkprom $$i; \ + done + +clean: + rm -f $(object-files) + +distclean: + rm -rf $(asm-files) libprom.a diff --git a/arch/mips/mips/mkprom b/arch/mips/mips/mkprom new file mode 100755 index 000000000..9e4cdf465 --- /dev/null +++ b/arch/mips/mips/mkprom @@ -0,0 +1,25 @@ +# +# Generate PROM library stubs for the firmware used in the +# Mips Computer System, Inc. machines. Beware: some of the +# machines seem to be different. +# +# Copyright (C) 1997 Ralf Baechle +# +fname=$1 +ucase=`echo $fname | tr 'a-z' 'A-Z'` +cat << EOF | sed -e "s/@1@/$fname/" -e "s/@2@/$ucase/" >$fname.S +/* + * WARNING: This file has been generated automatically. Do not edit! + * + * Stub for the Mips firmware @1@() function. + */ +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsprom.h> + +LEAF(mips_prom_@1@) + lw t0,__mips_prom_entry_offset + addu t0,PROM_@2@ + jr t0 + END(mips_prom_@1@) +EOF diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index d12159903..1205b2bf3 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -9,6 +9,6 @@ O_TARGET := mm.o O_OBJS := extable.o init.o fault.o r4xx0.o r2300.o r6000.o tfp.o \ - andes.o loadmmu.o stack.o + andes.o loadmmu.o include $(TOPDIR)/Rules.make diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 4fdd98155..3ad703b1f 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -70,7 +70,7 @@ good_area: if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } - handle_mm_fault(vma, address, writeaccess); + handle_mm_fault(tsk, vma, address, writeaccess); up(&mm->mmap_sem); goto out; diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c index 5f1bcbfa6..f83f41df8 100644 --- a/arch/mips/mm/r4xx0.c +++ b/arch/mips/mm/r4xx0.c @@ -1,4 +1,4 @@ -/* $Id: r4xx0.c,v 1.19 1996/08/02 11:11:36 dm Exp $ +/* * r4xx0.c: R4000 processor variant specific MMU/Cache routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -325,28 +325,6 @@ static inline void r4k_flush_cache_all_d32i32(void) restore_flags(flags); } -static inline struct vm_area_struct * -find_mm_vma(struct mm_struct *mm, unsigned long addr) -{ - struct vm_area_struct * result = NULL; - - if (mm) { - struct vm_area_struct * tree = mm->mmap_avl; - for (;;) { - if (tree == avl_empty) - break; - if (tree->vm_end > addr) { - result = tree; - if (tree->vm_start <= addr) - break; - tree = tree->vm_avl_left; - } else - tree = tree->vm_avl_right; - } - } - return result; -} - static void r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, unsigned long start, @@ -362,7 +340,7 @@ r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s16d16i16(); @@ -407,7 +385,7 @@ r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s32d16i16(); @@ -451,7 +429,7 @@ static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s64d16i16(); @@ -495,7 +473,7 @@ static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s128d16i16(); @@ -539,7 +517,7 @@ static void r4k_flush_cache_range_s16d32i32(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s16d32i32(); @@ -583,7 +561,7 @@ static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s32d32i32(); @@ -627,7 +605,7 @@ static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s64d32i32(); @@ -671,7 +649,7 @@ static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, #ifdef DEBUG_CACHE printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); #endif - vma = find_mm_vma(mm, start); + vma = find_vma(mm, start); if(vma) { if(mm->context != current->mm->context) { r4k_flush_cache_all_s128d32i32(); diff --git a/arch/mips/mm/stack.c b/arch/mips/mm/stack.c deleted file mode 100644 index 89fb6dc64..000000000 --- a/arch/mips/mm/stack.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Kernel stack allocation/deallocation - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996, 1997 by Ralf Baechle - * - * (This is _bad_ if the free page pool is fragmented ...) - */ -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/processor.h> - -extern unsigned long alloc_kernel_stack(struct task_struct *tsk) -{ - unsigned long stack; - stack = __get_free_pages(GFP_KERNEL, 1, 0); - - return stack; -} - -extern void free_kernel_stack(unsigned long stack) -{ - free_pages(stack, 1); -} diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c index 19b744fdb..fe60c03c8 100644 --- a/arch/mips/sgi/kernel/indy_int.c +++ b/arch/mips/sgi/kernel/indy_int.c @@ -16,6 +16,8 @@ #include <linux/timex.h> #include <linux/malloc.h> #include <linux/random.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <asm/bitops.h> #include <asm/bootinfo.h> @@ -51,6 +53,7 @@ extern asmlinkage void indyIRQ(void); extern void rs_kgdb_hook(int); #endif +unsigned int local_irq_count[NR_CPUS]; unsigned long spurious_count = 0; /* Local IRQ's are layed out logically like this: @@ -255,6 +258,15 @@ int get_irq_list(char *buf) return len; } +atomic_t __mips_bh_counter; + +#ifdef __SMP__ +#error Send superfluous SMP boxes to ralf@uni-koblenz.de +#else +#define irq_enter(cpu, irq) (++local_irq_count[cpu]) +#define irq_exit(cpu, irq) (--local_irq_count[cpu]) +#endif + /* * do_IRQ handles IRQ's that have been installed without the * SA_INTERRUPT flag: it uses the full signal-handling return @@ -264,8 +276,9 @@ int get_irq_list(char *buf) */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { - lock_kernel(); struct irqaction * action = *(irq + irq_action); + + lock_kernel(); kstat.interrupts[irq]++; printk("Got irq %d, press a key.", irq); prom_getchar(); diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c index 58b7695b3..e0482e116 100644 --- a/arch/mips/sgi/kernel/setup.c +++ b/arch/mips/sgi/kernel/setup.c @@ -9,6 +9,7 @@ #include <linux/kernel.h> #include <linux/sched.h> +#include <asm/reboot.h> #include <asm/vector.h> #include <asm/sgialib.h> #include <asm/sgi.h> diff --git a/arch/mips/sgi/prom/misc.c b/arch/mips/sgi/prom/misc.c index 47051a1b3..53ee61cfe 100644 --- a/arch/mips/sgi/prom/misc.c +++ b/arch/mips/sgi/prom/misc.c @@ -1,9 +1,9 @@ -/* $Id: misc.c,v 1.3 1996/08/07 02:54:12 dm Exp $ +/* * misc.c: Miscellaneous ARCS PROM routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ - +#include <linux/config.h> #include <linux/kernel.h> #include <asm/sgialib.h> @@ -51,7 +51,9 @@ void prom_halt(void) { shutoff_r4600_cache(); initialize_kbd(); +#if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); +#endif cli(); romvec->halt(); } @@ -60,7 +62,9 @@ void prom_powerdown(void) { shutoff_r4600_cache(); initialize_kbd(); +#if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); +#endif cli(); romvec->pdown(); } @@ -70,7 +74,9 @@ void prom_restart(void) { shutoff_r4600_cache(); initialize_kbd(); +#if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); +#endif cli(); romvec->restart(); } @@ -79,7 +85,9 @@ void prom_reboot(void) { shutoff_r4600_cache(); initialize_kbd(); +#if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); +#endif cli(); romvec->reboot(); } @@ -88,7 +96,9 @@ void prom_imode(void) { shutoff_r4600_cache(); initialize_kbd(); +#if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); +#endif cli(); romvec->imode(); } diff --git a/arch/mips/sni/.cvsignore b/arch/mips/sni/.cvsignore new file mode 100644 index 000000000..4671378ae --- /dev/null +++ b/arch/mips/sni/.cvsignore @@ -0,0 +1 @@ +.depend diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index f0bc3e600..9bd570ff0 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile @@ -13,7 +13,7 @@ all: sni.o O_TARGET := sni.o -O_OBJS := hw-access.o int-handler.o pci.o reset.o setup.o +O_OBJS := hw-access.o int-handler.o io.o pci.o reset.o setup.o int-handler.o: int-handler.S diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S index f60c82251..d051c8b13 100644 --- a/arch/mips/sni/int-handler.S +++ b/arch/mips/sni/int-handler.S @@ -1,7 +1,7 @@ /* * SNI RM200 PCI specific interrupt handler code. * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle + * Copyright (C) 1994 - 1997 by Ralf Baechle */ #include <asm/asm.h> #include <linux/config.h> @@ -150,30 +150,17 @@ poll_second: li a0,0x0f #endif /* CONFIG_PCNET32 */ -/* - * FIXME: This is definatly wrong but I'll have to do it this way - * 'till I get more hardware info. - * XXX: Apparently the NCR is attached to interrupt #2. - */ #ifdef CONFIG_SCSI_NCR53C8XX /* - * FIXME: detect this address - */ -#define NCR_BASE 0xb8000000 - -/* Offsets from base I/O address. */ -#define NCR_INTF 0x14 - -/* * ... check if we were interrupted by the NCR ... */ -3: lb t0,NCR_BASE+NCR_INTF - andi t0,7 - beqz t0,3f # no NCR interrupt? +3: lb t0,PCIMT_CSITPEND + andi t0,0x40 + bnez t0,3f # bit 6 == 0 -> SCSI IRQ nop # delay slot jal do_fast_IRQ - li a0,5 # delay slot + li a0,PCIMT_IRQ_SCSI # delay slot j return nop # delay slot diff --git a/arch/mips/sni/io.c b/arch/mips/sni/io.c new file mode 100644 index 000000000..f62fdc2d7 --- /dev/null +++ b/arch/mips/sni/io.c @@ -0,0 +1,172 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Low level I/O functions for SNI. + */ +#include <linux/string.h> +#include <asm/mipsconfig.h> +#include <asm/addrspace.h> +#include <asm/system.h> +#include <asm/spinlock.h> +#include <asm/sni.h> + +unsigned char sni_map_isa_cache; + +#define unused __attribute__((unused)) + +/* + * The PCIMT_CSMAPISA is shared by all processors; we need locking. + * + * XXX It's legal to use all the I/O memory access functions in interrupt + * code, so we need to use the _irq locking stuff which may result in + * significant IRQ latencies. + */ +static spinlock_t csmapisa_lock unused = SPIN_LOCK_UNLOCKED; + +/* + * Urgs... We only can see a 16mb window of the 4gb EISA address space + * at PCIMT_EISA_BASE. Maladia segmentitis ... + * + * XXX Check out if accessing PCIMT_CSMAPISA really is slow. + * For now assume so. + */ +static inline void update_isa_cache(unsigned long address) +{ + unsigned char upper; + + upper = address >> 24; + if (sni_map_isa_cache != upper) { + sni_map_isa_cache = upper; + *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper; + } +} + +static unsigned char sni_readb(unsigned long addr) +{ + unsigned char res; + + spin_lock_irq(&csmapisa_lock); + update_isa_cache(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr); + spin_unlock_irq(&csmapisa_lock); + + return res; +} + +static unsigned short sni_readw(unsigned long addr) +{ + unsigned short res; + + spin_lock_irq(&csmapisa_lock); + update_isa_cache(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr); + spin_unlock_irq(&csmapisa_lock); + + return res; +} + +static unsigned int sni_readl(unsigned long addr) +{ + unsigned int res; + + spin_lock_irq(&csmapisa_lock); + update_isa_cache(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr); + spin_unlock_irq(&csmapisa_lock); + + return res; +} + +static void sni_writeb(unsigned char val, unsigned long addr) +{ + spin_lock_irq(&csmapisa_lock); + update_isa_cache(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val; + spin_unlock_irq(&csmapisa_lock); +} + +static void sni_writew(unsigned short val, unsigned long addr) +{ + spin_lock_irq(&csmapisa_lock); + update_isa_cache(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val; + spin_unlock_irq(&csmapisa_lock); +} + +static void sni_writel(unsigned int val, unsigned long addr) +{ + spin_lock_irq(&csmapisa_lock); + update_isa_cache(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val; + spin_unlock_irq(&csmapisa_lock); +} + +static void sni_memset_io(unsigned long addr, int val, unsigned long len) +{ + unsigned long waddr; + + waddr = PCIMT_EISA_BASE | (addr & 0xffffff); + spin_lock_irq(&csmapisa_lock); + while(len) { + unsigned long fraglen; + + fraglen = (~addr + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + update_isa_cache(addr); + memset((char *)waddr, val, fraglen); + addr += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } + spin_unlock_irq(&csmapisa_lock); +} + +static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len) +{ + unsigned long waddr; + + waddr = PCIMT_EISA_BASE | (from & 0xffffff); + spin_lock_irq(&csmapisa_lock); + while(len) { + unsigned long fraglen; + + fraglen = (~from + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + update_isa_cache(from); + memcpy((void *)to, (void *)waddr, fraglen); + to += fraglen; + from += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } + spin_unlock_irq(&csmapisa_lock); +} + +static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len) +{ + unsigned long waddr; + + waddr = PCIMT_EISA_BASE | (to & 0xffffff); + spin_lock_irq(&csmapisa_lock); + while(len) { + unsigned long fraglen; + + fraglen = (~to + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + update_isa_cache(to); + memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen); + to += fraglen; + from += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } + spin_unlock_irq(&csmapisa_lock); +} diff --git a/arch/mips/sni/pci.c b/arch/mips/sni/pci.c index 06edb268f..917d07a81 100644 --- a/arch/mips/sni/pci.c +++ b/arch/mips/sni/pci.c @@ -7,6 +7,7 @@ */ #include <linux/config.h> #include <linux/bios32.h> +#include <linux/init.h> #include <linux/pci.h> #include <linux/types.h> #include <asm/byteorder.h> @@ -18,18 +19,26 @@ extern inline u32 mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where) { - return (((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | - ((where & 0xfc))); + return ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | + (where & 0xfc); } static unsigned long sni_rm200_pcibios_fixup (unsigned long memory_start, unsigned long memory_end) { - /* I guess it's ok to do exactly nothing. */ + /* + * TODO: Fix PCI_INTERRUPT_LINE register for onboard cards. + * Take care of RM300 revision D boards for where the network + * slot became an ordinary PCI slot. + */ return memory_start; } +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ static int sni_rm200_pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn, unsigned char where, @@ -39,7 +48,7 @@ static int sni_rm200_pcibios_read_config_byte (unsigned char bus, *(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where); res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = le32_to_cpu(res); + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; *val = res; return PCIBIOS_SUCCESSFUL; @@ -56,7 +65,7 @@ static int sni_rm200_pcibios_read_config_word (unsigned char bus, return PCIBIOS_BAD_REGISTER_NUMBER; *(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where); res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = le32_to_cpu(res); + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; *val = res; return PCIBIOS_SUCCESSFUL; @@ -110,7 +119,7 @@ static int sni_rm200_pcibios_write_config_dword (unsigned char bus, return PCIBIOS_SUCCESSFUL; } -unsigned long sni_rm200_pcibios_init(unsigned long memory_start, unsigned long memory_end) +__initfunc(unsigned long sni_rm200_pcibios_init(unsigned long memory_start, unsigned long memory_end)) { _pcibios_fixup = sni_rm200_pcibios_fixup; _pcibios_read_config_byte = sni_rm200_pcibios_read_config_byte; diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index 1a7a1387d..7fa76a490 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -5,11 +5,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 1997 by Ralf Baechle */ #include <asm/ptrace.h> #include <linux/ioport.h> #include <linux/sched.h> +#include <linux/init.h> #include <linux/interrupt.h> #include <linux/timex.h> #include <linux/pci.h> @@ -40,8 +41,7 @@ extern void sni_machine_restart(char *command); extern void sni_machine_halt(void); extern void sni_machine_power_off(void); -static void -sni_irq_setup(void) +__initfunc(static void sni_irq_setup(void)) { set_except_vector(0, sni_rm200_pci_handle_int); request_region(0x20,0x20, "pic1"); @@ -57,7 +57,7 @@ sni_irq_setup(void) void (*board_time_init)(struct irqaction *irq); -static void sni_rm200_pci_time_init(struct irqaction *irq) +__initfunc(static void sni_rm200_pci_time_init(struct irqaction *irq)) { /* set the clock to 100 Hz */ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ @@ -67,8 +67,9 @@ static void sni_rm200_pci_time_init(struct irqaction *irq) } unsigned char aux_device_present; -unsigned long sni_rm200_pcibios_init (unsigned long memory_start, - unsigned long memory_end); +extern unsigned long sni_rm200_pcibios_init (unsigned long memory_start, + unsigned long memory_end); +extern unsigned char sni_map_isa_cache; /* * A bit more gossip about the iron we're running on ... @@ -92,8 +93,7 @@ static inline void sni_pcimt_detect(void) printk("%s.\n", boardtype); } -void -sni_rm200_pci_setup(void) +__initfunc(void sni_rm200_pci_setup(void)) { tag *atag; @@ -127,7 +127,14 @@ sni_rm200_pci_setup(void) fd_cacheflush = sni_fd_cacheflush; // Will go away feature = &sni_rm200_pci_feature; port_base = SNI_PORT_BASE; + + /* + * Setup (E)ISA I/O memory access stuff + */ isa_slot_offset = 0xb0000000; + // sni_map_isa_cache = 0; + EISA_bus = 1; + request_region(0x00,0x20,"dma1"); request_region(0x40,0x20,"timer"); /* XXX FIXME: CONFIG_RTC */ @@ -140,8 +147,6 @@ sni_rm200_pci_setup(void) _machine_halt = sni_machine_halt; _machine_power_off = sni_machine_power_off; - if (mips_machtype == MACH_SNI_RM200_PCI) - EISA_bus = 1; aux_device_present = 0xaa; /* diff --git a/arch/mips/tools/.cvsignore b/arch/mips/tools/.cvsignore new file mode 100644 index 000000000..2a1642034 --- /dev/null +++ b/arch/mips/tools/.cvsignore @@ -0,0 +1 @@ +.depend offset.s offset.h diff --git a/arch/mips/tools/offset.c b/arch/mips/tools/offset.c index 3bb46de6e..a8660dcf6 100644 --- a/arch/mips/tools/offset.c +++ b/arch/mips/tools/offset.c @@ -77,12 +77,11 @@ void output_task_defines(void) { text("/* MIPS task_struct offsets. */"); offset("#define TASK_STATE ", struct task_struct, state); + offset("#define TASK_COUNTER ", struct task_struct, counter); offset("#define TASK_PRIORITY ", struct task_struct, priority); offset("#define TASK_SIGNAL ", struct task_struct, signal); offset("#define TASK_BLOCKED ", struct task_struct, blocked); offset("#define TASK_FLAGS ", struct task_struct, flags); - offset("#define TASK_SAVED_KSTACK ", struct task_struct, saved_kernel_stack); - offset("#define TASK_KSTACK_PG ", struct task_struct, kernel_stack_page); offset("#define TASK_MM ", struct task_struct, mm); linefeed; } diff --git a/arch/mips/tools/offset.h b/arch/mips/tools/offset.h deleted file mode 100644 index c5e6f37fa..000000000 --- a/arch/mips/tools/offset.h +++ /dev/null @@ -1,89 +0,0 @@ -/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */ - -#ifndef _MIPS_OFFSET_H -#define _MIPS_OFFSET_H - -/* MIPS pt_regs offsets. */ -#define PT_R0 24 -#define PT_R1 28 -#define PT_R2 32 -#define PT_R3 36 -#define PT_R4 40 -#define PT_R5 44 -#define PT_R6 48 -#define PT_R7 52 -#define PT_R8 56 -#define PT_R9 60 -#define PT_R10 64 -#define PT_R11 68 -#define PT_R12 72 -#define PT_R13 76 -#define PT_R14 80 -#define PT_R15 84 -#define PT_R16 88 -#define PT_R17 92 -#define PT_R18 96 -#define PT_R19 100 -#define PT_R20 104 -#define PT_R21 108 -#define PT_R22 112 -#define PT_R23 116 -#define PT_R24 120 -#define PT_R25 124 -#define PT_R26 128 -#define PT_R27 132 -#define PT_R28 136 -#define PT_R29 140 -#define PT_R30 144 -#define PT_R31 148 -#define PT_LO 152 -#define PT_HI 156 -#define PT_OR2 160 -#define PT_OR7 164 -#define PT_EPC 168 -#define PT_BVADDR 172 -#define PT_STATUS 176 -#define PT_CAUSE 180 -#define PT_SIZE 184 - -/* MIPS task_struct offsets. */ -#define TASK_STATE 0 -#define TASK_PRIORITY 8 -#define TASK_SIGNAL 12 -#define TASK_BLOCKED 16 -#define TASK_FLAGS 20 -#define TASK_SAVED_KSTACK 84 -#define TASK_KSTACK_PG 88 -#define TASK_MM 912 - -/* MIPS specific thread_struct offsets. */ -#define THREAD_REG16 544 -#define THREAD_REG17 548 -#define THREAD_REG18 552 -#define THREAD_REG19 556 -#define THREAD_REG20 560 -#define THREAD_REG21 564 -#define THREAD_REG22 568 -#define THREAD_REG23 572 -#define THREAD_REG28 576 -#define THREAD_REG29 580 -#define THREAD_REG30 584 -#define THREAD_REG31 588 -#define THREAD_STATUS 592 -#define THREAD_FPU 600 -#define THREAD_BVADDR 864 -#define THREAD_ECODE 868 -#define THREAD_TRAPNO 872 -#define THREAD_KSP 876 -#define THREAD_PGDIR 880 -#define THREAD_MFLAGS 884 -#define THREAD_CURDS 888 -#define THREAD_TRAMP 892 -#define THREAD_OLDCTX 896 - -/* Linux mm_struct offsets. */ -#define MM_COUNT 0 -#define MM_PGD 4 -#define MM_CONTEXT 8 - -#endif /* !(_MIPS_OFFSET_H) */ |