Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv32129/kernel Modified Files: cpu_ka42.c cpu_ka43.c cpu_ka46.c interrupt.c process.c reboot.c setup.c signal.c syscall.c Log Message: New mm layer, start of signals implementation + other misc fixes Index: cpu_ka42.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka42.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- cpu_ka42.c 2001/06/26 18:59:00 1.5 +++ cpu_ka42.c 2001/07/31 17:28:26 1.6 @@ -28,6 +28,7 @@ unsigned int sidex; }; + struct ka42_machine_vector mv_ka42 = { { ka42_pre_vm_init, Index: cpu_ka43.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka43.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- cpu_ka43.c 2001/06/26 18:59:00 1.6 +++ cpu_ka43.c 2001/07/31 17:28:26 1.7 @@ -10,6 +10,7 @@ * Fixed the cache initializing, added the functions * ka43_cache_disbale/enable/clear and moved some stuff around. * atp jun 2001 - machine check implementation + * atp Jul 2001 - diagmem remap functions */ #include <linux/types.h> /* For NULL */ @@ -22,6 +23,7 @@ #include <asm/mv.h> #include <asm/vaxcpu.h> #include <asm/vsa.h> +#include <asm/mm/tlb.h> #include <asm/ka43.h> void ka43_pre_vm_init(void); @@ -188,12 +190,12 @@ /* tell us all about it */ printk("KA43: machine check %d (0x%x)\n", ka43frame->mc43_code, ka43frame->mc43_code); printk("KA43: reason: %s\n", ka43_mctype[ka43frame->mc43_code & 0xff]); - + printk("KA43: at addr %x, pc %x, psl %x\n",ka43frame->mc43_addr,ka43frame->mc43_pc,ka43frame->mc43_psl); /* fixme check restart and first part done flags */ if ((ka43frame->mc43_code & KA43_MC_RESTART) || (ka43frame->mc43_psl & KA43_PSL_FPDONE)) { - printk("ka43_mchk: recovering from machine-check.\n"); + printk("KA43: recovering from machine-check.\n"); ka43_cache_reset(); /* reset caches */ return; /* go on; */ } @@ -202,4 +204,32 @@ printk("KA43: Machine Check - unknown error state - halting\n"); machine_halt(); +} + +/* slap the KA43_DIAGMEM bit on an area of S0 memory - used by drivers */ +/* size is the size of the region in bytes */ +void ka43_diagmem_remap(unsigned long int address, unsigned long int size) +{ + /* + * The KA43 seems to be nicely fscked up... All physical memory + * is accessible from 0x00000000 up (as normal) and also from + * 0x28000000 (KA43_DIAGMEM) in IO space. In order to reliably + * share memory with the LANCE, we _must_ read and write to this + * shared memory via the DIAGMEM region. Maybe this bypasses + * caches or something... If you don't do this you get evil + * "memory read parity error" machine checks. + */ + + /* You MUST remember to clear the DIAGMEM bits in these PTEs + before giving the pages back to free_pages() */ + + int i; + pte_t *p = GET_SPTE_VIRT(address); + + printk(KERN_DEBUG "KA43: enabling KA43_DIAGMEM for memory from (%8lx) to (%8lx)\n",address, address+size); + + for (i=0; i<(size>>PAGE_SHIFT); i++, p++) { + set_pte(p, __pte(pte_val(*p) | (KA43_DIAGMEM >> PAGELET_SHIFT))); + __flush_tlb_one(address + i * PAGE_SIZE); + } } Index: cpu_ka46.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka46.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- cpu_ka46.c 2001/06/26 18:59:00 1.6 +++ cpu_ka46.c 2001/07/31 17:28:26 1.7 @@ -16,6 +16,7 @@ #include <asm/mtpr.h> #include <asm/mv.h> #include <asm/vaxcpu.h> +#include <asm/vsa.h> #include <asm/ka46.h> void ka46_pre_vm_init(void); Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- interrupt.c 2001/06/26 18:59:00 1.12 +++ interrupt.c 2001/07/31 17:28:26 1.13 @@ -75,7 +75,7 @@ /* asm("movl %0, r2\n" "movl %1 ,r3\n" "movl %2 ,r4\n" - "halt" : : "g"(q), "g"(t), "g"(s) ); */ + "halt" : : "g"(q), "g"(t), "g"(s) );*/ set_pte(q, p); __flush_tlb_one(interrupt_stack[smp_processor_id()]); Index: process.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/process.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- process.c 2001/05/27 16:17:42 1.9 +++ process.c 2001/07/31 17:28:26 1.10 @@ -193,12 +193,12 @@ newsp = regs->sp; } -/* printk("sys_clone: calling do_fork(0x%08lx, 0x%08lx, 0x%p)\n", - clone_flags, newsp, regs); */ + printk("sys_clone: calling do_fork(0x%08lx, 0x%08lx, 0x%p)\n", + clone_flags, newsp, regs); retval = do_fork(clone_flags, newsp, regs, 0); -/* printk("sys_clone: do_fork() returned %d\n", retval); */ + printk("sys_clone: do_fork() returned %d\n", retval); return retval; } Index: reboot.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/reboot.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- reboot.c 2001/06/26 18:59:00 1.2 +++ reboot.c 2001/07/31 17:28:26 1.3 @@ -62,6 +62,7 @@ { if (mv->mcheck == NULL) { printk("machine check - CPU specific handler not implemented - halting\n"); + show_cpu_regs(); machine_halt(); } mv->mcheck(stkframe); Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/setup.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- setup.c 2001/06/26 18:59:00 1.9 +++ setup.c 2001/07/31 17:28:26 1.10 @@ -28,6 +28,7 @@ /* Defined in arch/vax/mm/init.c */ extern void paging_init(void); +unsigned long max_pfn; /* number of 4k pfns */ /* Linker will put this at the end of the kernel image */ extern char _end; @@ -56,6 +57,8 @@ void __init setup_arch(char **cmdline_p) { + unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 }; + unsigned int max_dma; unsigned long bootmap_size; unsigned long region_start; unsigned long region_len; @@ -74,8 +77,13 @@ /* Get the SID */ vax_cpu.sid = __mfpr(PR_SID); - /* Initialize bootmem */ + /* We expand the system page table in paging_init, so + * it comes before the bootmem allocator. */ + paging_init(); + + /* Initialize bootmem */ + /* We don't have any holes in our physical memory layout, so we throw everything into the bootmem allocator. Eventually, we will get smarter and use the bad page lists @@ -96,15 +104,26 @@ printk("calling free_bootmem(start=%08lx, len=%08lx)\n", region_start, region_len); free_bootmem(region_start, region_len); + - region_start = __pa(SPT_BASE + SPT_SIZE); + region_start = __pa(SPT_BASE + SPT_SIZE); region_len = (max_pfn << PAGE_SHIFT) - __pa(SPT_BASE + SPT_SIZE); printk("calling free_bootmem(start=%08lx, len=%08lx)\n", region_start, region_len); free_bootmem(region_start, region_len); + + max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + + /* max_pfn is the number of 4k ptes */ + if (max_pfn < max_dma) { + zones_size[ZONE_DMA] = max_pfn; + } else { + zones_size[ZONE_DMA] = max_dma; + zones_size[ZONE_NORMAL] = max_pfn - max_dma; + } - paging_init(); + free_area_init(zones_size); /* Set up the initial PCB. We can refer to current because head.S has already set us up on the kernel stack of task 0. */ Index: signal.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/signal.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- signal.c 2001/05/27 16:35:13 1.2 +++ signal.c 2001/07/31 17:28:26 1.3 @@ -3,10 +3,13 @@ This file contains the standard functions that the arch-independent kernel expects for signal handling + + Copyright, 1998-2001 atp, kenn, airlied. + + atp Jul 2001, signal handling, based on S390/Intel version. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/smp.h> @@ -17,23 +20,157 @@ #include <linux/wait.h> #include <linux/ptrace.h> #include <linux/unistd.h> - -#include <asm/bitops.h> -#include <asm/pgalloc.h> +#include <linux/stddef.h> +#include <asm/ucontext.h> #include <asm/uaccess.h> -/* FIXME: obviously, these need to be filled in... */ +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -int sys_sigaction(void) -{ - return -ENOSYS; -} +asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); -int sys_sigsuspend(void) +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) + return -EFAULT; + if (from->si_code < 0) + return __copy_to_user(to, from, sizeof(siginfo_t)); + else { + int err; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + /* First 32bits of unions are always present. */ + err |= __put_user(from->si_pid, &to->si_pid); + switch (from->si_code >> 16) { + case __SI_FAULT >> 16: + break; + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_uid, &to->si_uid); + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ + } + return err; + } +} + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int +sys_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sigmask_lock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + regs->r2 = -EINTR; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (do_signal(regs, &saveset)) + return -EINTR; + } +} + +asmlinkage int +sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sigmask_lock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + regs->r2 = -EINTR; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (do_signal(regs, &saveset)) + return -EINTR; + } +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (verify_area(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} +asmlinkage int +sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) +{ + return do_sigaltstack(uss, uoss, regs->sp); /* is ->sp the right one FIXME: check */ +} + + +/* + * Do a signal return; undo the signal stack. + */ + +struct sigframe { + struct sigcontext sc; + unsigned long extramask[_NSIG_WORDS-1]; + unsigned char retcode[8]; /* trampoline code */ +}; + +struct rt_sigframe { + struct siginfo *pinfo; + void *puc; + struct siginfo info; + struct ucontext uc; + unsigned char retcode[8]; /* trampoline code */ +}; - return -ENOSYS; -} int sys_sigreturn(void) { @@ -45,48 +182,5 @@ return -ENOSYS; } -int sys_rt_sigsuspend(void) -{ - return -ENOSYS; -} -int sys_sigaltstack(void) -{ - return -ENOSYS; -} -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } - -} Index: syscall.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/syscall.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- syscall.c 2001/01/29 00:58:54 1.3 +++ syscall.c 2001/07/31 17:28:26 1.4 @@ -78,7 +78,7 @@ nr_args = *user_ap; } -/* printk("Dispatching syscall %d with %d args\n", chmk_arg, nr_args); */ +/* printk("Dispatching syscall %d with %d args\n", chmk_arg, nr_args);*/ /* We pass all the user-supplied args plus the pointer to the regs to the syscall function. If the syscall is implemented @@ -115,7 +115,7 @@ "g"(-EFAULT) : "r0","r1","r2","r3","r4","r5" /* clobbers*/ ); -/* printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0); */ +/* printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0);*/ return; } |