Submitted By: Jim Gifford (patches at jg555 dot com) Date: 2006-11-29 Initial Package Version: 2.6.19 Origin: Linux-MIPS Upstream Status: http://www.linux-mips.org/pub/linux/mips/kernel/v2.6/ diff -Naur linux-2.6.19/arch/mips/Kconfig linux-mips-2.6.19/arch/mips/Kconfig --- linux-2.6.19/arch/mips/Kconfig 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/Kconfig 2006-11-29 15:23:09.000000000 -0800 @@ -468,8 +468,6 @@ config MACH_VR41XX bool "NEC VR41XX-based machines" select SYS_HAS_CPU_VR41XX - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL config PMC_YOSEMITE bool "PMC-Sierra Yosemite eval board" @@ -1142,7 +1140,7 @@ select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL help - The options selects support for the NEC VR4100 series of processors. + The options selects support for the NEC VR41xx series of processors. Only choose this option if you have one of these processors as a kernel built with this option will not run on any other type of processor or vice versa. @@ -1922,6 +1920,11 @@ depends on MIPS32_COMPAT default y +config SYSVIPC_COMPAT + bool + depends on COMPAT && SYSVIPC + default y + config MIPS32_O32 bool "Kernel support for o32 binaries" depends on MIPS32_COMPAT diff -Naur linux-2.6.19/arch/mips/au1000/common/pci.c linux-mips-2.6.19/arch/mips/au1000/common/pci.c --- linux-2.6.19/arch/mips/au1000/common/pci.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/au1000/common/pci.c 2006-11-29 15:23:09.000000000 -0800 @@ -76,13 +76,17 @@ } #ifdef CONFIG_DMA_NONCOHERENT - /* - * Set the NC bit in controller for Au1500 pre-AC silicon - */ - u32 prid = read_c0_prid(); - if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { - au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG); - printk("Non-coherent PCI accesses enabled\n"); + { + /* + * Set the NC bit in controller for Au1500 pre-AC silicon + */ + u32 prid = read_c0_prid(); + + if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { + au_writel((1 << 16) | au_readl(Au1500_PCI_CFG), + Au1500_PCI_CFG); + printk("Non-coherent PCI accesses enabled\n"); + } } #endif diff -Naur linux-2.6.19/arch/mips/au1000/common/setup.c linux-mips-2.6.19/arch/mips/au1000/common/setup.c --- linux-2.6.19/arch/mips/au1000/common/setup.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/au1000/common/setup.c 2006-11-29 15:23:09.000000000 -0800 @@ -141,17 +141,20 @@ /* This routine should be valid for all Au1x based boards */ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) { - u32 start, end; - /* Don't fixup 36 bit addresses */ - if ((phys_addr >> 32) != 0) return phys_addr; + if ((phys_addr >> 32) != 0) + return phys_addr; #ifdef CONFIG_PCI - start = (u32)Au1500_PCI_MEM_START; - end = (u32)Au1500_PCI_MEM_END; - /* check for pci memory window */ - if ((phys_addr >= start) && ((phys_addr + size) < end)) { - return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START); + { + u32 start, end; + + start = (u32)Au1500_PCI_MEM_START; + end = (u32)Au1500_PCI_MEM_END; + /* check for pci memory window */ + if ((phys_addr >= start) && ((phys_addr + size) < end)) + return (phys_t) + ((phys_addr - start) + Au1500_PCI_MEM_START); } #endif diff -Naur linux-2.6.19/arch/mips/au1000/pb1100/board_setup.c linux-mips-2.6.19/arch/mips/au1000/pb1100/board_setup.c --- linux-2.6.19/arch/mips/au1000/pb1100/board_setup.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/au1000/pb1100/board_setup.c 2006-11-29 15:23:09.000000000 -0800 @@ -47,8 +47,7 @@ void __init board_setup(void) { - u32 pin_func; - u32 sys_freqctrl, sys_clksrc; + volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL; // set AUX clock to 12MHz * 8 = 96 MHz au_writel(8, SYS_AUXPLL); @@ -56,58 +55,62 @@ udelay(100); #ifdef CONFIG_USB_OHCI - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + { + u32 pin_func, sys_freqctrl, sys_clksrc; - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD/IrDA clock */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* - * Route 48MHz FREQ2 into USBH/USBD/IrDA - */ - sys_clksrc |= ((4<<2) | (0<<1) | 0 ); - au_writel(sys_clksrc, SYS_CLKSRC); - - /* setup the static bus controller */ - au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ - au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ - au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - - // get USB Functionality pin state (device vs host drive pins) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); - // 2nd USB port is USB host - pin_func |= 0x8000; - au_writel(pin_func, SYS_PINFUNC); + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD/IrDA clock */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USBH/USBD/IrDA + */ + sys_clksrc |= ((4<<2) | (0<<1) | 0 ); + au_writel(sys_clksrc, SYS_CLKSRC); + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + + // get USB Functionality pin state (device vs host drive pins) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + // 2nd USB port is USB host + pin_func |= 0x8000; + au_writel(pin_func, SYS_PINFUNC); + } #endif // defined (CONFIG_USB_OHCI) /* Enable sys bus clock divider when IDLE state or no bus activity. */ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); // Enable the RTC if not already enabled - if (!(readb(0xac000028) & 0x20)) { - writeb(readb(0xac000028) | 0x20, 0xac000028); + if (!(readb(base + 0x28) & 0x20)) { + writeb(readb(base + 0x28) | 0x20, base + 0x28); au_sync(); } // Put the clock in BCD mode - if (readb(0xac00002C) & 0x4) { /* reg B */ - writeb(readb(0xac00002c) & ~0x4, 0xac00002c); + if (readb(base + 0x2C) & 0x4) { /* reg B */ + writeb(readb(base + 0x2c) & ~0x4, base + 0x2c); au_sync(); } } diff -Naur linux-2.6.19/arch/mips/kernel/linux32.c linux-mips-2.6.19/arch/mips/kernel/linux32.c --- linux-2.6.19/arch/mips/kernel/linux32.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/kernel/linux32.c 2006-11-29 15:23:09.000000000 -0800 @@ -382,531 +382,6 @@ return ret; } -struct msgbuf32 { s32 mtype; char mtext[1]; }; - -struct ipc_perm32 -{ - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; -}; - -struct ipc64_perm32 { - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; - unsigned short __pad1; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct semid_ds32 { - struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ - compat_time_t sem_otime; /* last semop time */ - compat_time_t sem_ctime; /* last change time */ - u32 sem_base; /* ptr to first semaphore in array */ - u32 sem_pending; /* pending operations to be processed */ - u32 sem_pending_last; /* last pending operation */ - u32 undo; /* undo requests on this array */ - unsigned short sem_nsems; /* no. of semaphores in array */ -}; - -struct semid64_ds32 { - struct ipc64_perm32 sem_perm; - compat_time_t sem_otime; - compat_time_t sem_ctime; - unsigned int sem_nsems; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct msqid_ds32 -{ - struct ipc_perm32 msg_perm; - u32 msg_first; - u32 msg_last; - compat_time_t msg_stime; - compat_time_t msg_rtime; - compat_time_t msg_ctime; - u32 wwait; - u32 rwait; - unsigned short msg_cbytes; - unsigned short msg_qnum; - unsigned short msg_qbytes; - compat_ipc_pid_t msg_lspid; - compat_ipc_pid_t msg_lrpid; -}; - -struct msqid64_ds32 { - struct ipc64_perm32 msg_perm; - compat_time_t msg_stime; - unsigned int __unused1; - compat_time_t msg_rtime; - unsigned int __unused2; - compat_time_t msg_ctime; - unsigned int __unused3; - unsigned int msg_cbytes; - unsigned int msg_qnum; - unsigned int msg_qbytes; - compat_pid_t msg_lspid; - compat_pid_t msg_lrpid; - unsigned int __unused4; - unsigned int __unused5; -}; - -struct shmid_ds32 { - struct ipc_perm32 shm_perm; - int shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_ipc_pid_t shm_cpid; - compat_ipc_pid_t shm_lpid; - unsigned short shm_nattch; -}; - -struct shmid64_ds32 { - struct ipc64_perm32 shm_perm; - compat_size_t shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_pid_t shm_cpid; - compat_pid_t shm_lpid; - unsigned int shm_nattch; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct ipc_kludge32 { - u32 msgp; - s32 msgtyp; -}; - -static int -do_sys32_semctl(int first, int second, int third, void __user *uptr) -{ - union semun fourth; - u32 pad; - int err, err2; - struct semid64_ds s; - mm_segment_t old_fs; - - if (!uptr) - return -EINVAL; - err = -EFAULT; - if (get_user (pad, (u32 __user *)uptr)) - return err; - if ((third & ~IPC_64) == SETVAL) - fourth.val = (int)pad; - else - fourth.__pad = (void __user *)A(pad); - switch (third & ~IPC_64) { - case IPC_INFO: - case IPC_RMID: - case IPC_SET: - case SEM_INFO: - case GETVAL: - case GETPID: - case GETNCNT: - case GETZCNT: - case GETALL: - case SETVAL: - case SETALL: - err = sys_semctl (first, second, third, fourth); - break; - - case IPC_STAT: - case SEM_STAT: - fourth.__pad = (struct semid64_ds __user *)&s; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_semctl(first, second, third | IPC_64, fourth); - set_fs(old_fs); - - if (third & IPC_64) { - struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad); - - if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { - err = -EFAULT; - break; - } - err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); - err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); - err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); - err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); - err2 |= __put_user(s.sem_otime, &usp64->sem_otime); - err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); - err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); - } else { - struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad); - - if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { - err = -EFAULT; - break; - } - err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); - err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); - err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); - err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); - err2 |= __put_user(s.sem_otime, &usp32->sem_otime); - err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); - err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); - } - if (err2) - err = -EFAULT; - break; - - default: - err = - EINVAL; - break; - } - - return err; -} - -static int -do_sys32_msgsnd (int first, int second, int third, void __user *uptr) -{ - struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr; - struct msgbuf *p; - mm_segment_t old_fs; - int err; - - if (second < 0) - return -EINVAL; - p = kmalloc (second + sizeof (struct msgbuf) - + 4, GFP_USER); - if (!p) - return -ENOMEM; - err = get_user (p->mtype, &up->mtype); - if (err) - goto out; - err |= __copy_from_user (p->mtext, &up->mtext, second); - if (err) - goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third); - set_fs (old_fs); -out: - kfree (p); - - return err; -} - -static int -do_sys32_msgrcv (int first, int second, int msgtyp, int third, - int version, void __user *uptr) -{ - struct msgbuf32 __user *up; - struct msgbuf *p; - mm_segment_t old_fs; - int err; - - if (!version) { - struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr; - struct ipc_kludge32 ipck; - - err = -EINVAL; - if (!uptr) - goto out; - err = -EFAULT; - if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32))) - goto out; - uptr = (void __user *)AA(ipck.msgp); - msgtyp = ipck.msgtyp; - } - - if (second < 0) - return -EINVAL; - err = -ENOMEM; - p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); - if (!p) - goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third); - set_fs (old_fs); - if (err < 0) - goto free_then_out; - up = (struct msgbuf32 __user *)uptr; - if (put_user (p->mtype, &up->mtype) || - __copy_to_user (&up->mtext, p->mtext, err)) - err = -EFAULT; -free_then_out: - kfree (p); -out: - return err; -} - -static int -do_sys32_msgctl (int first, int second, void __user *uptr) -{ - int err = -EINVAL, err2; - struct msqid64_ds m; - struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr; - struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr; - mm_segment_t old_fs; - - switch (second & ~IPC_64) { - case IPC_INFO: - case IPC_RMID: - case MSG_INFO: - err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr); - break; - - case IPC_SET: - if (second & IPC_64) { - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid); - err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid); - err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode); - err |= __get_user(m.msg_qbytes, &up64->msg_qbytes); - } else { - if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid); - err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid); - err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode); - err |= __get_user(m.msg_qbytes, &up32->msg_qbytes); - } - if (err) - break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); - set_fs(old_fs); - break; - - case IPC_STAT: - case MSG_STAT: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); - set_fs(old_fs); - if (second & IPC_64) { - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key); - err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid); - err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid); - err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid); - err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid); - err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode); - err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq); - err2 |= __put_user(m.msg_stime, &up64->msg_stime); - err2 |= __put_user(m.msg_rtime, &up64->msg_rtime); - err2 |= __put_user(m.msg_ctime, &up64->msg_ctime); - err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes); - err2 |= __put_user(m.msg_qnum, &up64->msg_qnum); - err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes); - err2 |= __put_user(m.msg_lspid, &up64->msg_lspid); - err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid); - if (err2) - err = -EFAULT; - } else { - if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key); - err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid); - err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid); - err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid); - err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid); - err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode); - err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq); - err2 |= __put_user(m.msg_stime, &up32->msg_stime); - err2 |= __put_user(m.msg_rtime, &up32->msg_rtime); - err2 |= __put_user(m.msg_ctime, &up32->msg_ctime); - err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes); - err2 |= __put_user(m.msg_qnum, &up32->msg_qnum); - err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes); - err2 |= __put_user(m.msg_lspid, &up32->msg_lspid); - err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid); - if (err2) - err = -EFAULT; - } - break; - } - - return err; -} - -static int -do_sys32_shmat (int first, int second, int third, int version, void __user *uptr) -{ - unsigned long raddr; - u32 __user *uaddr = (u32 __user *)A((u32)third); - int err = -EINVAL; - - if (version == 1) - return err; - err = do_shmat (first, uptr, second, &raddr); - if (err) - return err; - err = put_user (raddr, uaddr); - return err; -} - -struct shm_info32 { - int used_ids; - u32 shm_tot, shm_rss, shm_swp; - u32 swap_attempts, swap_successes; -}; - -static int -do_sys32_shmctl (int first, int second, void __user *uptr) -{ - struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr; - struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr; - struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr; - int err = -EFAULT, err2; - struct shmid64_ds s64; - mm_segment_t old_fs; - struct shm_info si; - struct shmid_ds s; - - switch (second & ~IPC_64) { - case IPC_INFO: - second = IPC_INFO; /* So that we don't have to translate it */ - case IPC_RMID: - case SHM_LOCK: - case SHM_UNLOCK: - err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr); - break; - case IPC_SET: - if (second & IPC_64) { - err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); - } else { - err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); - } - if (err) - break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s); - set_fs(old_fs); - break; - - case IPC_STAT: - case SHM_STAT: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second | IPC_64, (void __user *) &s64); - set_fs(old_fs); - if (err < 0) - break; - if (second & IPC_64) { - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); - err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); - err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); - err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); - err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); - err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); - err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); - err2 |= __put_user(s64.shm_atime, &up64->shm_atime); - err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); - err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); - err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); - err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); - err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); - err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); - } else { - if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); - err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); - err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); - err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); - err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); - err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); - err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); - err2 |= __put_user(s64.shm_atime, &up32->shm_atime); - err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); - err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); - err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); - err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); - err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); - err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); - } - if (err2) - err = -EFAULT; - break; - - case SHM_INFO: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second, (void __user *)&si); - set_fs(old_fs); - if (err < 0) - break; - err2 = put_user(si.used_ids, &uip->used_ids); - err2 |= __put_user(si.shm_tot, &uip->shm_tot); - err2 |= __put_user(si.shm_rss, &uip->shm_rss); - err2 |= __put_user(si.shm_swp, &uip->shm_swp); - err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); - err2 |= __put_user (si.swap_successes, &uip->swap_successes); - if (err2) - err = -EFAULT; - break; - - default: - err = -EINVAL; - break; - } - - return err; -} - -static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems, - const struct compat_timespec __user *timeout32) -{ - struct compat_timespec t32; - struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64)); - - if (copy_from_user(&t32, timeout32, sizeof(t32))) - return -EFAULT; - - if (put_user(t32.tv_sec, &t64->tv_sec) || - put_user(t32.tv_nsec, &t64->tv_nsec)) - return -EFAULT; - - return sys_semtimedop(semid, tsems, nsems, t64); -} - asmlinkage long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -918,48 +393,43 @@ switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second, - NULL); + err = sys_semtimedop(first, compat_ptr(ptr), second, NULL); break; case SEMTIMEDOP: - err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second, - (const struct compat_timespec __user *)AA(fifth)); + err = compat_sys_semtimedop(first, compat_ptr(ptr), second, + compat_ptr(fifth)); break; case SEMGET: - err = sys_semget (first, second, third); + err = sys_semget(first, second, third); break; case SEMCTL: - err = do_sys32_semctl (first, second, third, - (void __user *)AA(ptr)); + err = compat_sys_semctl(first, second, third, compat_ptr(ptr)); break; - case MSGSND: - err = do_sys32_msgsnd (first, second, third, - (void __user *)AA(ptr)); + err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr)); break; case MSGRCV: - err = do_sys32_msgrcv (first, second, fifth, third, - version, (void __user *)AA(ptr)); + err = compat_sys_msgrcv(first, second, fifth, third, + version, compat_ptr(ptr)); break; case MSGGET: - err = sys_msgget ((key_t) first, second); + err = sys_msgget((key_t) first, second); break; case MSGCTL: - err = do_sys32_msgctl (first, second, (void __user *)AA(ptr)); + err = compat_sys_msgctl(first, second, compat_ptr(ptr)); break; - case SHMAT: - err = do_sys32_shmat (first, second, third, - version, (void __user *)AA(ptr)); + err = compat_sys_shmat(first, second, third, version, + compat_ptr(ptr)); break; case SHMDT: - err = sys_shmdt ((char __user *)A(ptr)); + err = sys_shmdt(compat_ptr(ptr)); break; case SHMGET: - err = sys_shmget (first, (unsigned)second, third); + err = sys_shmget(first, (unsigned)second, third); break; case SHMCTL: - err = do_sys32_shmctl (first, second, (void __user *)AA(ptr)); + err = compat_sys_shmctl(first, second, compat_ptr(ptr)); break; default: err = -EINVAL; @@ -969,18 +439,16 @@ return err; } -asmlinkage long sys32_shmat(int shmid, char __user *shmaddr, - int shmflg, int32_t __user *addr) +#ifdef CONFIG_MIPS32_N32 +asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg) { - unsigned long raddr; - int err; - - err = do_shmat(shmid, shmaddr, shmflg, &raddr); - if (err) - return err; - - return put_user(raddr, addr); + /* compat_sys_semctl expects a pointer to union semun */ + u32 __user *uptr = compat_alloc_user_space(sizeof(u32)); + if (put_user(ptr_to_compat(arg.__pad), uptr)) + return -EFAULT; + return compat_sys_semctl(semid, semnum, cmd, uptr); } +#endif struct sysctl_args32 { diff -Naur linux-2.6.19/arch/mips/kernel/mips-mt.c linux-mips-2.6.19/arch/mips/kernel/mips-mt.c --- linux-2.6.19/arch/mips/kernel/mips-mt.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/kernel/mips-mt.c 2006-11-29 15:23:09.000000000 -0800 @@ -96,6 +96,10 @@ goto out_unlock; } + retval = security_task_setscheduler(p, 0, NULL); + if (retval) + goto out_unlock; + /* Record new user-specified CPU set for future reference */ p->thread.user_cpus_allowed = new_mask; @@ -141,8 +145,9 @@ p = find_process_by_pid(pid); if (!p) goto out_unlock; - - retval = 0; + retval = security_task_getscheduler(p); + if (retval) + goto out_unlock; cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); diff -Naur linux-2.6.19/arch/mips/kernel/ptrace.c linux-mips-2.6.19/arch/mips/kernel/ptrace.c --- linux-2.6.19/arch/mips/kernel/ptrace.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/kernel/ptrace.c 2006-11-29 15:23:09.000000000 -0800 @@ -20,12 +20,12 @@ #include #include #include -#include #include #include #include #include -#include +#include +#include #include #include @@ -473,12 +473,16 @@ */ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { + /* do the secure computing check first */ + secure_computing(regs->orig_eax); + if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), regs->regs[2]); if (!(current->ptrace & PT_PTRACED)) goto out; + if (!test_thread_flag(TIF_SYSCALL_TRACE)) goto out; @@ -496,9 +500,14 @@ send_sig(current->exit_code, current, 1); current->exit_code = 0; } - out: + +out: + /* There is no ->orig_eax and that's quite intensional for now making + this work will require some work in various other place before it's + more than a placebo. */ + if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(audit_arch(), regs->regs[2], - regs->regs[4], regs->regs[5], - regs->regs[6], regs->regs[7]); + audit_syscall_entry(audit_arch(), regs->orig_eax, + regs->regs[4], regs->regs[5], + regs->regs[6], regs->regs[7]); } diff -Naur linux-2.6.19/arch/mips/kernel/scall64-n32.S linux-mips-2.6.19/arch/mips/kernel/scall64-n32.S --- linux-2.6.19/arch/mips/kernel/scall64-n32.S 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/kernel/scall64-n32.S 2006-11-29 15:23:09.000000000 -0800 @@ -149,8 +149,8 @@ PTR sys_mincore PTR sys_madvise PTR sys_shmget - PTR sys32_shmat - PTR sys_shmctl /* 6030 */ + PTR sys_shmat + PTR compat_sys_shmctl /* 6030 */ PTR sys_dup PTR sys_dup2 PTR sys_pause @@ -184,12 +184,12 @@ PTR sys32_newuname PTR sys_semget PTR sys_semop - PTR sys_semctl + PTR sysn32_semctl PTR sys_shmdt /* 6065 */ PTR sys_msgget - PTR sys_msgsnd - PTR sys_msgrcv - PTR sys_msgctl + PTR compat_sys_msgsnd + PTR compat_sys_msgrcv + PTR compat_sys_msgctl PTR compat_sys_fcntl /* 6070 */ PTR sys_flock PTR sys_fsync @@ -335,7 +335,7 @@ PTR compat_sys_fcntl64 PTR sys_set_tid_address PTR sys_restart_syscall - PTR sys_semtimedop /* 6215 */ + PTR compat_sys_semtimedop /* 6215 */ PTR sys_fadvise64_64 PTR compat_sys_statfs64 PTR compat_sys_fstatfs64 diff -Naur linux-2.6.19/arch/mips/lib/Makefile linux-mips-2.6.19/arch/mips/lib/Makefile --- linux-2.6.19/arch/mips/lib/Makefile 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/lib/Makefile 2006-11-29 15:23:09.000000000 -0800 @@ -5,8 +5,6 @@ lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \ strnlen_user.o uncached.o -obj-y += iomap.o - # libgcc-style stuff needed in the kernel lib-y += ashldi3.o ashrdi3.o lshrdi3.o diff -Naur linux-2.6.19/arch/mips/lib/iomap.c linux-mips-2.6.19/arch/mips/lib/iomap.c --- linux-2.6.19/arch/mips/lib/iomap.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/lib/iomap.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,78 +0,0 @@ -/* - * iomap.c, Memory Mapped I/O routines for MIPS architecture. - * - * This code is based on lib/iomap.c, by Linus Torvalds. - * - * Copyright (C) 2004-2005 Yoichi Yuasa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include - -#include - -void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - unsigned long end; - - end = port + nr - 1UL; - if (ioport_resource.start > port || - ioport_resource.end < end || port > end) - return NULL; - - return (void __iomem *)(mips_io_port_base + port); -} - -void ioport_unmap(void __iomem *addr) -{ -} -EXPORT_SYMBOL(ioport_map); -EXPORT_SYMBOL(ioport_unmap); - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - unsigned long start, len, flags; - - if (dev == NULL) - return NULL; - - start = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - if (!start || !len) - return NULL; - - if (maxlen != 0 && len > maxlen) - len = maxlen; - - flags = pci_resource_flags(dev, bar); - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap_cachable(start, len); - return ioremap_nocache(start, len); - } - - return NULL; -} - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iomap); -EXPORT_SYMBOL(pci_iounmap); diff -Naur linux-2.6.19/arch/mips/lib-32/dump_tlb.c linux-mips-2.6.19/arch/mips/lib-32/dump_tlb.c --- linux-2.6.19/arch/mips/lib-32/dump_tlb.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/lib-32/dump_tlb.c 2006-11-29 15:23:09.000000000 -0800 @@ -40,8 +40,6 @@ return "256Mb"; #endif } - - return "unknown"; } #define BARRIER() \ diff -Naur linux-2.6.19/arch/mips/lib-64/dump_tlb.c linux-mips-2.6.19/arch/mips/lib-64/dump_tlb.c --- linux-2.6.19/arch/mips/lib-64/dump_tlb.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/lib-64/dump_tlb.c 2006-11-29 15:23:09.000000000 -0800 @@ -31,8 +31,6 @@ case PM_256M: return "256Mb"; #endif } - - return "unknown"; } #define BARRIER() \ diff -Naur linux-2.6.19/arch/mips/mm/init.c linux-mips-2.6.19/arch/mips/mm/init.c --- linux-2.6.19/arch/mips/mm/init.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/mm/init.c 2006-11-29 15:23:09.000000000 -0800 @@ -203,6 +203,31 @@ preempt_check_resched(); } +void copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma) +{ + void *vfrom, *vto; + + vto = kmap_atomic(to, KM_USER1); + if (cpu_has_dc_aliases) { + vfrom = kmap_coherent(from, vaddr); + copy_page(vto, vfrom); + kunmap_coherent(from); + } else { + vfrom = kmap_atomic(from, KM_USER0); + copy_page(vto, vfrom); + kunmap_atomic(vfrom, KM_USER0); + } + if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) || + pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) + flush_data_cache_page((unsigned long)vto); + kunmap_atomic(vto, KM_USER1); + /* Make sure this page is cleared on other CPU's too before using it */ + smp_wmb(); +} + +EXPORT_SYMBOL(copy_user_highpage); + void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) diff -Naur linux-2.6.19/arch/mips/momentum/jaguar_atx/Makefile linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/Makefile --- linux-2.6.19/arch/mips/momentum/jaguar_atx/Makefile 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/Makefile 2006-11-29 15:23:09.000000000 -0800 @@ -6,7 +6,7 @@ # unless it's something special (ie not a .c file). # -obj-y += irq.o prom.o reset.o setup.o +obj-y += irq.o platform.o prom.o reset.o setup.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o diff -Naur linux-2.6.19/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h --- linux-2.6.19/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h 2006-11-29 15:23:09.000000000 -0800 @@ -46,7 +46,9 @@ extern unsigned long ja_fpga_base; -#define JAGUAR_FPGA_WRITE(x,y) writeb(x, ja_fpga_base + JAGUAR_ATX_REG_##y) -#define JAGUAR_FPGA_READ(x) readb(ja_fpga_base + JAGUAR_ATX_REG_##x) +#define __FPGA_REG_TO_ADDR(reg) \ + ((void *) ja_fpga_base + JAGUAR_ATX_REG_##reg) +#define JAGUAR_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) +#define JAGUAR_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) #endif diff -Naur linux-2.6.19/arch/mips/momentum/jaguar_atx/platform.c linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/platform.c --- linux-2.6.19/arch/mips/momentum/jaguar_atx/platform.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/platform.c 2006-11-29 15:23:09.000000000 -0800 @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include + +#include "jaguar_atx_fpga.h" + +#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +#define MV_SRAM_BASE 0xfe000000UL +#define MV_SRAM_SIZE (256 * 1024) + +#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) +#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) + +#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE +#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) + +#define MV64x60_IRQ_ETH_0 48 +#define MV64x60_IRQ_ETH_1 49 +#define MV64x60_IRQ_ETH_2 50 + +#ifdef CONFIG_MV643XX_ETH_0 + +static struct resource mv64x60_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = MV64x60_IRQ_ETH_0, + .end = MV64x60_IRQ_ETH_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth0_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth0_pd = { + .mac_addr = eth0_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH0, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), + .resource = mv64x60_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_0 */ + +#ifdef CONFIG_MV643XX_ETH_1 + +static struct resource mv64x60_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = MV64x60_IRQ_ETH_1, + .end = MV64x60_IRQ_ETH_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth1_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth1_pd = { + .mac_addr = eth1_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH1, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), + .resource = mv64x60_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_1 */ + +#ifdef CONFIG_MV643XX_ETH_2 + +static struct resource mv64x60_eth2_resources[] = { + [0] = { + .name = "eth2 irq", + .start = MV64x60_IRQ_ETH_2, + .end = MV64x60_IRQ_ETH_2, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth2_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth2_pd = { + .mac_addr = eth2_mac_addr, +}; + +static struct platform_device eth2_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), + .resource = mv64x60_eth2_resources, + .dev = { + .platform_data = ð2_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_2 */ + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, +#ifdef CONFIG_MV643XX_ETH_0 + ð0_device, +#endif +#ifdef CONFIG_MV643XX_ETH_1 + ð1_device, +#endif +#ifdef CONFIG_MV643XX_ETH_2 + ð2_device, +#endif +}; + +static u8 __init exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + udelay(1); + + /* turn the clock on */ + JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + udelay(1); + + /* turn the clock off and read-strobe */ + JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return (JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; +} + +static void __init get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} + +/* + * Copy and increment ethernet MAC address by a small value. + * + * This is useful for systems where the only one MAC address is stored in + * non-volatile memory for multiple ports. + */ +static inline void eth_mac_add(unsigned char *dst, unsigned char *src, + unsigned int add) +{ + int i; + + BUG_ON(add >= 256); + + for (i = ETH_ALEN; i >= 0; i--) { + dst[i] = src[i] + add; + add = dst[i] < src[i]; /* compute carry */ + } + + WARN_ON(add); +} + +static int __init mv643xx_eth_add_pds(void) +{ + unsigned char mac[ETH_ALEN]; + int ret; + + get_mac(mac); +#ifdef CONFIG_MV643XX_ETH_0 + eth_mac_add(eth1_mac_addr, mac, 0); +#endif +#ifdef CONFIG_MV643XX_ETH_1 + eth_mac_add(eth1_mac_addr, mac, 1); +#endif +#ifdef CONFIG_MV643XX_ETH_2 + eth_mac_add(eth2_mac_addr, mac, 2); +#endif + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); + +#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff -Naur linux-2.6.19/arch/mips/momentum/jaguar_atx/prom.c linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/prom.c --- linux-2.6.19/arch/mips/momentum/jaguar_atx/prom.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/momentum/jaguar_atx/prom.c 2006-11-29 15:23:09.000000000 -0800 @@ -39,56 +39,6 @@ return "Momentum Jaguar-ATX"; } -#ifdef CONFIG_MV643XX_ETH -extern unsigned char prom_mac_addr_base[6]; - -static void burn_clocks(void) -{ - int i; - - /* this loop should burn at least 1us -- this should be plenty */ - for (i = 0; i < 0x10000; i++) - ; -} - -static u8 exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - burn_clocks(); - - /* turn the clock on */ - JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - burn_clocks(); - - /* turn the clock off and read-strobe */ - JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return ((JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); -} - -void get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} -#endif - #ifdef CONFIG_64BIT unsigned long signext(unsigned long addr) @@ -228,11 +178,6 @@ #endif /* CONFIG_64BIT */ mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_JAGUAR_ATX; - -#ifdef CONFIG_MV643XX_ETH - /* get the base MAC address for on-board ethernet ports */ - get_mac(prom_mac_addr_base); -#endif } unsigned long __init prom_free_prom_memory(void) diff -Naur linux-2.6.19/arch/mips/pci/fixup-tb0219.c linux-mips-2.6.19/arch/mips/pci/fixup-tb0219.c --- linux-2.6.19/arch/mips/pci/fixup-tb0219.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/pci/fixup-tb0219.c 2006-11-29 15:23:09.000000000 -0800 @@ -2,7 +2,7 @@ * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. * * Copyright (C) 2003 Megasolution Inc. - * Copyright (C) 2004 Yoichi Yuasa + * Copyright (C) 2004-2005 Yoichi Yuasa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Naur linux-2.6.19/arch/mips/qemu/Makefile linux-mips-2.6.19/arch/mips/qemu/Makefile --- linux-2.6.19/arch/mips/qemu/Makefile 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/qemu/Makefile 2006-11-29 15:23:09.000000000 -0800 @@ -4,4 +4,5 @@ obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o +obj-$(CONFIG_VT) += q-vga.o obj-$(CONFIG_SMP) += q-smp.o diff -Naur linux-2.6.19/arch/mips/qemu/q-setup.c linux-mips-2.6.19/arch/mips/qemu/q-setup.c --- linux-2.6.19/arch/mips/qemu/q-setup.c 2006-11-29 13:57:37.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/qemu/q-setup.c 2006-11-29 15:23:09.000000000 -0800 @@ -2,6 +2,7 @@ #include #include +extern void qvga_init(void); extern void qemu_reboot_setup(void); #define QEMU_PORT_BASE 0xb4000000 @@ -23,5 +24,9 @@ void __init plat_mem_setup(void) { set_io_port_base(QEMU_PORT_BASE); +#ifdef CONFIG_VT + qvga_init(); +#endif + qemu_reboot_setup(); } diff -Naur linux-2.6.19/arch/mips/qemu/q-vga.c linux-mips-2.6.19/arch/mips/qemu/q-vga.c --- linux-2.6.19/arch/mips/qemu/q-vga.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-mips-2.6.19/arch/mips/qemu/q-vga.c 2006-11-29 15:23:09.000000000 -0800 @@ -0,0 +1,189 @@ +/* + * 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) 2005 by Ralf Baechle (ralf@linux-mips.org) + * + * This will eventually go into the qemu firmware. + */ +#include +#include +#include +#include +#include