aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-07 19:14:20 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-07 19:14:20 -0500
commit24bfb00123e82a2e70bd115277d922438813515b (patch)
tree27328b8a5718e16d64e2d101f4b7ddcad5930aed /arch
parentc6135234550ed89a6fd0e8cb229633967e41d649 (diff)
parent3f00d3e8fb963968a922d821a9a53b503b687e81 (diff)
Merge ../linux-2.6
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/ptrace.c49
-rw-r--r--arch/arm/mach-aaec2000/clock.c1
-rw-r--r--arch/arm/mach-epxa10db/mm.c1
-rw-r--r--arch/arm/mach-integrator/impd1.c3
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c1
-rw-r--r--arch/arm26/kernel/ptrace.c49
-rw-r--r--arch/cris/arch-v10/README.mm6
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c51
-rw-r--r--arch/cris/arch-v10/kernel/signal.c2
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c14
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c51
-rw-r--r--arch/cris/arch-v32/kernel/signal.c2
-rw-r--r--arch/cris/mm/ioremap.c2
-rw-r--r--arch/frv/kernel/ptrace.c43
-rw-r--r--arch/h8300/kernel/ptrace.c39
-rw-r--r--arch/i386/Kconfig13
-rw-r--r--arch/i386/Kconfig.debug10
-rw-r--r--arch/i386/kernel/apic.c10
-rw-r--r--arch/i386/kernel/apm.c5
-rw-r--r--arch/i386/kernel/cpu/common.c5
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/k7.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/mce.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p4.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p5.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/p6.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/winchip.c2
-rw-r--r--arch/i386/kernel/kprobes.c180
-rw-r--r--arch/i386/kernel/ldt.c1
-rw-r--r--arch/i386/kernel/mca.c2
-rw-r--r--arch/i386/kernel/ptrace.c44
-rw-r--r--arch/i386/kernel/reboot_fixups.c3
-rw-r--r--arch/i386/kernel/scx200.c1
-rw-r--r--arch/i386/kernel/smpboot.c4
-rw-r--r--arch/i386/oprofile/Kconfig6
-rw-r--r--arch/i386/power/cpu.c1
-rw-r--r--arch/ia64/Kconfig13
-rw-r--r--arch/ia64/Kconfig.debug11
-rw-r--r--arch/ia64/hp/sim/simserial.c6
-rw-r--r--arch/ia64/kernel/kprobes.c126
-rw-r--r--arch/ia64/kernel/perfmon.c2
-rw-r--r--arch/ia64/kernel/setup.c7
-rw-r--r--arch/ia64/oprofile/Kconfig6
-rw-r--r--arch/m68k/atari/time.c6
-rw-r--r--arch/m68k/kernel/ptrace.c47
-rw-r--r--arch/m68knommu/Kconfig17
-rw-r--r--arch/m68knommu/Makefile7
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c1
-rw-r--r--arch/m68knommu/kernel/ptrace.c39
-rw-r--r--arch/m68knommu/kernel/setup.c5
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S9
-rw-r--r--arch/m68knommu/platform/520x/Makefile19
-rw-r--r--arch/m68knommu/platform/520x/config.c65
-rw-r--r--arch/m68knommu/platform/5307/Makefile1
-rw-r--r--arch/m68knommu/platform/5307/head.S3
-rw-r--r--arch/m68knommu/platform/5307/ints.c1
-rw-r--r--arch/m68knommu/platform/5307/pit.c12
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/boot/.gitignore4
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig11
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig10
-rw-r--r--arch/mips/ddb5xxx/common/rtc_ds1386.c6
-rw-r--r--arch/mips/dec/time.c24
-rw-r--r--arch/mips/jmr3927/common/rtc_ds1742.c6
-rw-r--r--arch/mips/kernel/irixsig.c3
-rw-r--r--arch/mips/kernel/ptrace.c55
-rw-r--r--arch/mips/kernel/rtlx.c197
-rw-r--r--arch/mips/kernel/signal.c3
-rw-r--r--arch/mips/kernel/signal32.c13
-rw-r--r--arch/mips/kernel/vpe.c100
-rw-r--r--arch/mips/lasat/ds1603.c9
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c6
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c6
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c6
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c6
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c6
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c7
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c6
-rw-r--r--arch/parisc/kernel/ptrace.c50
-rw-r--r--arch/powerpc/Kconfig14
-rw-r--r--arch/powerpc/Kconfig.debug10
-rw-r--r--arch/powerpc/kernel/cputable.c10
-rw-r--r--arch/powerpc/kernel/ptrace.c43
-rw-r--r--arch/powerpc/kernel/time.c1
-rw-r--r--arch/powerpc/mm/hash_utils_64.c6
-rw-r--r--arch/powerpc/mm/hugetlbpage.c6
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c4
-rw-r--r--arch/powerpc/mm/slb_low.S13
-rw-r--r--arch/powerpc/oprofile/Kconfig6
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c6
-rw-r--r--arch/ppc/4xx_io/serial_sicc.c17
-rw-r--r--arch/ppc/8260_io/fcc_enet.c3
-rw-r--r--arch/ppc/8xx_io/cs4218_tdm.c3
-rw-r--r--arch/ppc/Kconfig18
-rw-r--r--arch/ppc/boot/simple/Makefile27
-rw-r--r--arch/ppc/boot/simple/misc.c16
-rw-r--r--arch/ppc/boot/simple/openbios.c106
-rw-r--r--arch/ppc/configs/ev64360_defconfig73
-rw-r--r--arch/ppc/configs/stx_gp3_defconfig86
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/head_44x.S4
-rw-r--r--arch/ppc/kernel/rio.c52
-rw-r--r--arch/ppc/platforms/4xx/Kconfig19
-rw-r--r--arch/ppc/platforms/4xx/Makefile2
-rw-r--r--arch/ppc/platforms/4xx/bubinga.c2
-rw-r--r--arch/ppc/platforms/4xx/bubinga.h64
-rw-r--r--arch/ppc/platforms/4xx/ebony.h4
-rw-r--r--arch/ppc/platforms/4xx/ppc440spe.c148
-rw-r--r--arch/ppc/platforms/4xx/ppc440spe.h66
-rw-r--r--arch/ppc/platforms/4xx/sycamore.c7
-rw-r--r--arch/ppc/platforms/4xx/sycamore.h67
-rw-r--r--arch/ppc/platforms/4xx/walnut.c2
-rw-r--r--arch/ppc/platforms/4xx/walnut.h67
-rw-r--r--arch/ppc/platforms/4xx/yucca.c395
-rw-r--r--arch/ppc/platforms/4xx/yucca.h111
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.c10
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c14
-rw-r--r--arch/ppc/platforms/ev64360.c12
-rw-r--r--arch/ppc/syslib/Makefile4
-rw-r--r--arch/ppc/syslib/ibm440sp_common.c4
-rw-r--r--arch/ppc/syslib/ibm44x_common.c12
-rw-r--r--arch/ppc/syslib/ppc405_pci.c7
-rw-r--r--arch/ppc/syslib/ppc440spe_pcie.c442
-rw-r--r--arch/ppc/syslib/ppc440spe_pcie.h149
-rw-r--r--arch/ppc/syslib/ppc4xx_pic.c37
-rw-r--r--arch/ppc/syslib/ppc85xx_rio.c938
-rw-r--r--arch/ppc/syslib/ppc85xx_rio.h21
-rw-r--r--arch/ppc/syslib/ppc_sys.c1
-rw-r--r--arch/ppc/syslib/prom.c6
-rw-r--r--arch/ppc64/boot/main.c11
-rw-r--r--arch/ppc64/kernel/kprobes.c138
-rw-r--r--arch/ppc64/kernel/lparcfg.c4
-rw-r--r--arch/ppc64/kernel/scanlog.c3
-rw-r--r--arch/s390/Makefile4
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/entry.S4
-rw-r--r--arch/s390/kernel/entry64.S4
-rw-r--r--arch/s390/kernel/head.S383
-rw-r--r--arch/s390/kernel/head31.S336
-rw-r--r--arch/s390/kernel/head64.S543
-rw-r--r--arch/s390/kernel/time.c8
-rw-r--r--arch/s390/kernel/traps.c29
-rw-r--r--arch/s390/mm/extmem.c8
-rw-r--r--arch/s390/mm/fault.c113
-rw-r--r--arch/sh/Kconfig28
-rw-r--r--arch/sh/Makefile8
-rw-r--r--arch/sh/drivers/Makefile5
-rw-r--r--arch/sh/drivers/superhyway/Makefile6
-rw-r--r--arch/sh/drivers/superhyway/ops-sh4-202.c171
-rw-r--r--arch/sh/kernel/ptrace.c44
-rw-r--r--arch/sh/kernel/setup.c26
-rw-r--r--arch/sh/mm/init.c21
-rw-r--r--arch/sh/mm/tlb-sh3.c19
-rw-r--r--arch/sh/ramdisk/Makefile20
-rw-r--r--arch/sh/ramdisk/ld.script9
-rw-r--r--arch/sh64/kernel/ptrace.c83
-rw-r--r--arch/sh64/kernel/syscalls.S2
-rw-r--r--arch/sparc64/Kconfig13
-rw-r--r--arch/sparc64/Kconfig.debug10
-rw-r--r--arch/sparc64/kernel/kprobes.c165
-rw-r--r--arch/sparc64/kernel/us2e_cpufreq.c7
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c7
-rw-r--r--arch/sparc64/oprofile/Kconfig6
-rw-r--r--arch/um/Kconfig46
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/Makefile-i3862
-rw-r--r--arch/um/drivers/chan_user.c1
-rw-r--r--arch/um/drivers/harddog_kern.c1
-rw-r--r--arch/um/drivers/harddog_user.c1
-rw-r--r--arch/um/drivers/net_kern.c38
-rw-r--r--arch/um/drivers/net_user.c1
-rw-r--r--arch/um/drivers/port_user.c1
-rw-r--r--arch/um/drivers/random.c6
-rw-r--r--arch/um/drivers/slip_user.c1
-rw-r--r--arch/um/drivers/slirp_user.c1
-rw-r--r--arch/um/drivers/xterm.c1
-rw-r--r--arch/um/include/helper.h27
-rw-r--r--arch/um/include/mem_user.h2
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h16
-rw-r--r--arch/um/include/sysdep-i386/stub.h64
-rw-r--r--arch/um/include/sysdep-x86_64/stub.h61
-rw-r--r--arch/um/include/uml_uaccess.h4
-rw-r--r--arch/um/kernel/Makefile7
-rw-r--r--arch/um/kernel/ksyms.c1
-rw-r--r--arch/um/kernel/mem.c4
-rw-r--r--arch/um/kernel/physmem.c4
-rw-r--r--arch/um/kernel/ptrace.c50
-rw-r--r--arch/um/kernel/sigio_user.c3
-rw-r--r--arch/um/kernel/skas/include/mmu-skas.h2
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/mem.c2
-rw-r--r--arch/um/kernel/skas/mmu.c44
-rw-r--r--arch/um/kernel/skas/process.c17
-rw-r--r--arch/um/kernel/skas/process_kern.c2
-rw-r--r--arch/um/kernel/tt/uaccess_user.c1
-rw-r--r--arch/um/kernel/uaccess.c30
-rw-r--r--arch/um/kernel/uaccess_user.c64
-rw-r--r--arch/um/kernel/um_arch.c10
-rw-r--r--arch/um/kernel/user_util.c1
-rw-r--r--arch/um/os-Linux/Makefile9
-rw-r--r--arch/um/os-Linux/aio.c1
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c1
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c1
-rw-r--r--arch/um/os-Linux/helper.c (renamed from arch/um/kernel/helper.c)18
-rw-r--r--arch/um/os-Linux/main.c (renamed from arch/um/kernel/main.c)49
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/start_up.c77
-rw-r--r--arch/um/os-Linux/uaccess.c32
-rw-r--r--arch/um/scripts/Makefile.rules7
-rw-r--r--arch/um/sys-i386/ldt.c506
-rw-r--r--arch/um/sys-x86_64/Makefile5
-rw-r--r--arch/um/sys-x86_64/syscalls.c75
-rw-r--r--arch/v850/kernel/ptrace.c43
-rw-r--r--arch/x86_64/Kconfig13
-rw-r--r--arch/x86_64/Kconfig.debug10
-rw-r--r--arch/x86_64/kernel/kprobes.c183
-rw-r--r--arch/x86_64/kernel/ptrace.c43
-rw-r--r--arch/x86_64/kernel/smpboot.c2
-rw-r--r--arch/x86_64/oprofile/Kconfig6
-rw-r--r--arch/xtensa/kernel/ptrace.c55
221 files changed, 5266 insertions, 3333 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 9bd8609a2926..9a340e790da5 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -648,7 +648,7 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
648 648
649#endif 649#endif
650 650
651static int do_ptrace(int request, struct task_struct *child, long addr, long data) 651long arch_ptrace(struct task_struct *child, long request, long addr, long data)
652{ 652{
653 unsigned long tmp; 653 unsigned long tmp;
654 int ret; 654 int ret;
@@ -782,53 +782,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
782 return ret; 782 return ret;
783} 783}
784 784
785asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
786{
787 struct task_struct *child;
788 int ret;
789
790 lock_kernel();
791 ret = -EPERM;
792 if (request == PTRACE_TRACEME) {
793 /* are we already being traced? */
794 if (current->ptrace & PT_PTRACED)
795 goto out;
796 ret = security_ptrace(current->parent, current);
797 if (ret)
798 goto out;
799 /* set the ptrace bit in the process flags. */
800 current->ptrace |= PT_PTRACED;
801 ret = 0;
802 goto out;
803 }
804 ret = -ESRCH;
805 read_lock(&tasklist_lock);
806 child = find_task_by_pid(pid);
807 if (child)
808 get_task_struct(child);
809 read_unlock(&tasklist_lock);
810 if (!child)
811 goto out;
812
813 ret = -EPERM;
814 if (pid == 1) /* you may not mess with init */
815 goto out_tsk;
816
817 if (request == PTRACE_ATTACH) {
818 ret = ptrace_attach(child);
819 goto out_tsk;
820 }
821 ret = ptrace_check_attach(child, request == PTRACE_KILL);
822 if (ret == 0)
823 ret = do_ptrace(request, child, addr, data);
824
825out_tsk:
826 put_task_struct(child);
827out:
828 unlock_kernel();
829 return ret;
830}
831
832asmlinkage void syscall_trace(int why, struct pt_regs *regs) 785asmlinkage void syscall_trace(int why, struct pt_regs *regs)
833{ 786{
834 unsigned long ip; 787 unsigned long ip;
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
index 99e019169dda..0340ddc4824e 100644
--- a/arch/arm/mach-aaec2000/clock.c
+++ b/arch/arm/mach-aaec2000/clock.c
@@ -14,6 +14,7 @@
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/string.h>
17 18
18#include <asm/semaphore.h> 19#include <asm/semaphore.h>
19#include <asm/hardware/clock.h> 20#include <asm/hardware/clock.h>
diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c
index e8832d0910ee..cfd0d2182d44 100644
--- a/arch/arm/mach-epxa10db/mm.c
+++ b/arch/arm/mach-epxa10db/mm.c
@@ -25,6 +25,7 @@
25#include <asm/hardware.h> 25#include <asm/hardware.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/sizes.h> 27#include <asm/sizes.h>
28#include <asm/page.h>
28 29
29#include <asm/mach/map.h> 30#include <asm/mach/map.h>
30 31
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index a1b153d1626c..a4bafee77a06 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -420,8 +420,7 @@ static int impd1_probe(struct lm_device *dev)
420 free_impd1: 420 free_impd1:
421 if (impd1 && impd1->base) 421 if (impd1 && impd1->base)
422 iounmap(impd1->base); 422 iounmap(impd1->base);
423 if (impd1) 423 kfree(impd1);
424 kfree(impd1);
425 release_lm: 424 release_lm:
426 release_mem_region(dev->resource.start, SZ_4K); 425 release_mem_region(dev->resource.start, SZ_4K);
427 return ret; 426 return ret;
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 54162ba95414..698eb06545c4 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/string.h>
22#include <asm/arch/akita.h> 23#include <asm/arch/akita.h>
23#include <asm/arch/corgi.h> 24#include <asm/arch/corgi.h>
24#include <asm/arch/hardware.h> 25#include <asm/arch/hardware.h>
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index cf7e977d18c8..4e6b7356a722 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -546,7 +546,7 @@ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
546 sizeof(struct user_fp)) ? -EFAULT : 0; 546 sizeof(struct user_fp)) ? -EFAULT : 0;
547} 547}
548 548
549static int do_ptrace(int request, struct task_struct *child, long addr, long data) 549long arch_ptrace(struct task_struct *child, long request, long addr, long data)
550{ 550{
551 unsigned long tmp; 551 unsigned long tmp;
552 int ret; 552 int ret;
@@ -665,53 +665,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
665 return ret; 665 return ret;
666} 666}
667 667
668asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
669{
670 struct task_struct *child;
671 int ret;
672
673 lock_kernel();
674 ret = -EPERM;
675 if (request == PTRACE_TRACEME) {
676 /* are we already being traced? */
677 if (current->ptrace & PT_PTRACED)
678 goto out;
679 ret = security_ptrace(current->parent, current);
680 if (ret)
681 goto out;
682 /* set the ptrace bit in the process flags. */
683 current->ptrace |= PT_PTRACED;
684 ret = 0;
685 goto out;
686 }
687 ret = -ESRCH;
688 read_lock(&tasklist_lock);
689 child = find_task_by_pid(pid);
690 if (child)
691 get_task_struct(child);
692 read_unlock(&tasklist_lock);
693 if (!child)
694 goto out;
695
696 ret = -EPERM;
697 if (pid == 1) /* you may not mess with init */
698 goto out_tsk;
699
700 if (request == PTRACE_ATTACH) {
701 ret = ptrace_attach(child);
702 goto out_tsk;
703 }
704 ret = ptrace_check_attach(child, request == PTRACE_KILL);
705 if (ret == 0)
706 ret = do_ptrace(request, child, addr, data);
707
708out_tsk:
709 put_task_struct(child);
710out:
711 unlock_kernel();
712 return ret;
713}
714
715asmlinkage void syscall_trace(int why, struct pt_regs *regs) 668asmlinkage void syscall_trace(int why, struct pt_regs *regs)
716{ 669{
717 unsigned long ip; 670 unsigned long ip;
diff --git a/arch/cris/arch-v10/README.mm b/arch/cris/arch-v10/README.mm
index 6f08903f3139..517d1f027fe8 100644
--- a/arch/cris/arch-v10/README.mm
+++ b/arch/cris/arch-v10/README.mm
@@ -177,7 +177,7 @@ The example address is 0xd004000c; in binary this is:
177Given the top-level Page Directory, the offset in that directory is calculated 177Given the top-level Page Directory, the offset in that directory is calculated
178using the upper 8 bits: 178using the upper 8 bits:
179 179
180extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) 180static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
181{ 181{
182 return mm->pgd + (address >> PGDIR_SHIFT); 182 return mm->pgd + (address >> PGDIR_SHIFT);
183} 183}
@@ -190,14 +190,14 @@ The pgd_t from our example will therefore be the 208'th (0xd0) entry in mm->pgd.
190 190
191Since the Middle Directory does not exist, it is a unity mapping: 191Since the Middle Directory does not exist, it is a unity mapping:
192 192
193extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) 193static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
194{ 194{
195 return (pmd_t *) dir; 195 return (pmd_t *) dir;
196} 196}
197 197
198The Page Table provides the final lookup by using bits 13 to 23 as index: 198The Page Table provides the final lookup by using bits 13 to 23 as index:
199 199
200extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) 200static inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
201{ 201{
202 return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & 202 return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) &
203 (PTRS_PER_PTE - 1)); 203 (PTRS_PER_PTE - 1));
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 130dd214e41d..6cbd34a27b90 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -76,55 +76,11 @@ ptrace_disable(struct task_struct *child)
76 * (in user space) where the result of the ptrace call is written (instead of 76 * (in user space) where the result of the ptrace call is written (instead of
77 * being returned). 77 * being returned).
78 */ 78 */
79asmlinkage int 79long arch_ptrace(struct task_struct *child, long request, long addr, long data)
80sys_ptrace(long request, long pid, long addr, long data)
81{ 80{
82 struct task_struct *child;
83 int ret; 81 int ret;
84 unsigned long __user *datap = (unsigned long __user *)data; 82 unsigned long __user *datap = (unsigned long __user *)data;
85 83
86 lock_kernel();
87 ret = -EPERM;
88
89 if (request == PTRACE_TRACEME) {
90 /* are we already being traced? */
91 if (current->ptrace & PT_PTRACED)
92 goto out;
93 ret = security_ptrace(current->parent, current);
94 if (ret)
95 goto out;
96 /* set the ptrace bit in the process flags. */
97 current->ptrace |= PT_PTRACED;
98 ret = 0;
99 goto out;
100 }
101
102 ret = -ESRCH;
103 read_lock(&tasklist_lock);
104 child = find_task_by_pid(pid);
105
106 if (child)
107 get_task_struct(child);
108
109 read_unlock(&tasklist_lock);
110
111 if (!child)
112 goto out;
113
114 ret = -EPERM;
115
116 if (pid == 1) /* Leave the init process alone! */
117 goto out_tsk;
118
119 if (request == PTRACE_ATTACH) {
120 ret = ptrace_attach(child);
121 goto out_tsk;
122 }
123
124 ret = ptrace_check_attach(child, request == PTRACE_KILL);
125 if (ret < 0)
126 goto out_tsk;
127
128 switch (request) { 84 switch (request) {
129 /* Read word at location address. */ 85 /* Read word at location address. */
130 case PTRACE_PEEKTEXT: 86 case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@ sys_ptrace(long request, long pid, long addr, long data)
289 ret = ptrace_request(child, request, addr, data); 245 ret = ptrace_request(child, request, addr, data);
290 break; 246 break;
291 } 247 }
292out_tsk: 248
293 put_task_struct(child);
294out:
295 unlock_kernel();
296 return ret; 249 return ret;
297} 250}
298 251
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 693771961f85..19bcad05716f 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -476,7 +476,7 @@ give_sigsegv:
476 * OK, we're invoking a handler 476 * OK, we're invoking a handler
477 */ 477 */
478 478
479extern inline void 479static inline void
480handle_signal(int canrestart, unsigned long sig, 480handle_signal(int canrestart, unsigned long sig,
481 siginfo_t *info, struct k_sigaction *ka, 481 siginfo_t *info, struct k_sigaction *ka,
482 sigset_t *oldset, struct pt_regs * regs) 482 sigset_t *oldset, struct pt_regs * regs)
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index ca72076c630a..501fa52d8d3a 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -277,7 +277,7 @@ struct file_operations cryptocop_fops = {
277static void free_cdesc(struct cryptocop_dma_desc *cdesc) 277static void free_cdesc(struct cryptocop_dma_desc *cdesc)
278{ 278{
279 DEBUG(printk("free_cdesc: cdesc 0x%p, from_pool=%d\n", cdesc, cdesc->from_pool)); 279 DEBUG(printk("free_cdesc: cdesc 0x%p, from_pool=%d\n", cdesc, cdesc->from_pool));
280 if (cdesc->free_buf) kfree(cdesc->free_buf); 280 kfree(cdesc->free_buf);
281 281
282 if (cdesc->from_pool) { 282 if (cdesc->from_pool) {
283 unsigned long int flags; 283 unsigned long int flags;
@@ -2950,15 +2950,15 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
2950 put_page(outpages[i]); 2950 put_page(outpages[i]);
2951 } 2951 }
2952 2952
2953 if (digest_result) kfree(digest_result); 2953 kfree(digest_result);
2954 if (inpages) kfree(inpages); 2954 kfree(inpages);
2955 if (outpages) kfree(outpages); 2955 kfree(outpages);
2956 if (cop){ 2956 if (cop){
2957 if (cop->tfrm_op.indata) kfree(cop->tfrm_op.indata); 2957 kfree(cop->tfrm_op.indata);
2958 if (cop->tfrm_op.outdata) kfree(cop->tfrm_op.outdata); 2958 kfree(cop->tfrm_op.outdata);
2959 kfree(cop); 2959 kfree(cop);
2960 } 2960 }
2961 if (jc) kfree(jc); 2961 kfree(jc);
2962 2962
2963 DEBUG(print_lock_status()); 2963 DEBUG(print_lock_status());
2964 2964
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 208489da2a87..5528b83a622b 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -99,55 +99,11 @@ ptrace_disable(struct task_struct *child)
99} 99}
100 100
101 101
102asmlinkage int 102long arch_ptrace(struct task_struct *child, long request, long addr, long data)
103sys_ptrace(long request, long pid, long addr, long data)
104{ 103{
105 struct task_struct *child;
106 int ret; 104 int ret;
107 unsigned long __user *datap = (unsigned long __user *)data; 105 unsigned long __user *datap = (unsigned long __user *)data;
108 106
109 lock_kernel();
110 ret = -EPERM;
111
112 if (request == PTRACE_TRACEME) {
113 /* are we already being traced? */
114 if (current->ptrace & PT_PTRACED)
115 goto out;
116 ret = security_ptrace(current->parent, current);
117 if (ret)
118 goto out;
119 /* set the ptrace bit in the process flags. */
120 current->ptrace |= PT_PTRACED;
121 ret = 0;
122 goto out;
123 }
124
125 ret = -ESRCH;
126 read_lock(&tasklist_lock);
127 child = find_task_by_pid(pid);
128
129 if (child)
130 get_task_struct(child);
131
132 read_unlock(&tasklist_lock);
133
134 if (!child)
135 goto out;
136
137 ret = -EPERM;
138
139 if (pid == 1) /* Leave the init process alone! */
140 goto out_tsk;
141
142 if (request == PTRACE_ATTACH) {
143 ret = ptrace_attach(child);
144 goto out_tsk;
145 }
146
147 ret = ptrace_check_attach(child, request == PTRACE_KILL);
148 if (ret < 0)
149 goto out_tsk;
150
151 switch (request) { 107 switch (request) {
152 /* Read word at location address. */ 108 /* Read word at location address. */
153 case PTRACE_PEEKTEXT: 109 case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@ sys_ptrace(long request, long pid, long addr, long data)
347 ret = ptrace_request(child, request, addr, data); 303 ret = ptrace_request(child, request, addr, data);
348 break; 304 break;
349 } 305 }
350out_tsk: 306
351 put_task_struct(child);
352out:
353 unlock_kernel();
354 return ret; 307 return ret;
355} 308}
356 309
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 0a3614dab887..99e59b3eacf8 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -513,7 +513,7 @@ give_sigsegv:
513} 513}
514 514
515/* Invoke a singal handler to, well, handle the signal. */ 515/* Invoke a singal handler to, well, handle the signal. */
516extern inline void 516static inline void
517handle_signal(int canrestart, unsigned long sig, 517handle_signal(int canrestart, unsigned long sig,
518 siginfo_t *info, struct k_sigaction *ka, 518 siginfo_t *info, struct k_sigaction *ka,
519 sigset_t *oldset, struct pt_regs * regs) 519 sigset_t *oldset, struct pt_regs * regs)
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index a92ac9877582..1780df3ed9e5 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -16,7 +16,7 @@
16#include <asm/tlbflush.h> 16#include <asm/tlbflush.h>
17#include <asm/arch/memmap.h> 17#include <asm/arch/memmap.h>
18 18
19extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 19static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
20 unsigned long phys_addr, pgprot_t prot) 20 unsigned long phys_addr, pgprot_t prot)
21{ 21{
22 unsigned long end; 22 unsigned long end;
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index cb335a14a315..f953484e7d59 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -106,48 +106,11 @@ void ptrace_enable(struct task_struct *child)
106 child->thread.frame0->__status |= REG__STATUS_STEP; 106 child->thread.frame0->__status |= REG__STATUS_STEP;
107} 107}
108 108
109asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 109long arch_ptrace(struct task_struct *child, long request, long addr, long data)
110{ 110{
111 struct task_struct *child;
112 unsigned long tmp; 111 unsigned long tmp;
113 int ret; 112 int ret;
114 113
115 lock_kernel();
116 ret = -EPERM;
117 if (request == PTRACE_TRACEME) {
118 /* are we already being traced? */
119 if (current->ptrace & PT_PTRACED)
120 goto out;
121 ret = security_ptrace(current->parent, current);
122 if (ret)
123 goto out;
124 /* set the ptrace bit in the process flags. */
125 current->ptrace |= PT_PTRACED;
126 ret = 0;
127 goto out;
128 }
129 ret = -ESRCH;
130 read_lock(&tasklist_lock);
131 child = find_task_by_pid(pid);
132 if (child)
133 get_task_struct(child);
134 read_unlock(&tasklist_lock);
135 if (!child)
136 goto out;
137
138 ret = -EPERM;
139 if (pid == 1) /* you may not mess with init */
140 goto out_tsk;
141
142 if (request == PTRACE_ATTACH) {
143 ret = ptrace_attach(child);
144 goto out_tsk;
145 }
146
147 ret = ptrace_check_attach(child, request == PTRACE_KILL);
148 if (ret < 0)
149 goto out_tsk;
150
151 switch (request) { 114 switch (request) {
152 /* when I and D space are separate, these will need to be fixed. */ 115 /* when I and D space are separate, these will need to be fixed. */
153 case PTRACE_PEEKTEXT: /* read word at location addr. */ 116 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
351 ret = -EIO; 314 ret = -EIO;
352 break; 315 break;
353 } 316 }
354out_tsk:
355 put_task_struct(child);
356out:
357 unlock_kernel();
358 return ret; 317 return ret;
359} 318}
360 319
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index a569fe4aa284..0ff6f79b0fed 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -57,43 +57,10 @@ void ptrace_disable(struct task_struct *child)
57 h8300_disable_trace(child); 57 h8300_disable_trace(child);
58} 58}
59 59
60asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 60long arch_ptrace(struct task_struct *child, long request, long addr, long data)
61{ 61{
62 struct task_struct *child;
63 int ret; 62 int ret;
64 63
65 lock_kernel();
66 ret = -EPERM;
67 if (request == PTRACE_TRACEME) {
68 /* are we already being traced? */
69 if (current->ptrace & PT_PTRACED)
70 goto out;
71 /* set the ptrace bit in the process flags. */
72 current->ptrace |= PT_PTRACED;
73 ret = 0;
74 goto out;
75 }
76 ret = -ESRCH;
77 read_lock(&tasklist_lock);
78 child = find_task_by_pid(pid);
79 if (child)
80 get_task_struct(child);
81 read_unlock(&tasklist_lock);
82 if (!child)
83 goto out;
84
85 ret = -EPERM;
86 if (pid == 1) /* you may not mess with init */
87 goto out_tsk;
88
89 if (request == PTRACE_ATTACH) {
90 ret = ptrace_attach(child);
91 goto out_tsk;
92 }
93 ret = ptrace_check_attach(child, request == PTRACE_KILL);
94 if (ret < 0)
95 goto out_tsk;
96
97 switch (request) { 64 switch (request) {
98 case PTRACE_PEEKTEXT: /* read word at location addr. */ 65 case PTRACE_PEEKTEXT: /* read word at location addr. */
99 case PTRACE_PEEKDATA: { 66 case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
251 ret = -EIO; 218 ret = -EIO;
252 break; 219 break;
253 } 220 }
254out_tsk:
255 put_task_struct(child);
256out:
257 unlock_kernel();
258 return ret; 221 return ret;
259} 222}
260 223
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index bac0da731ee3..dbf90ad6eac3 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -997,8 +997,21 @@ source "drivers/Kconfig"
997 997
998source "fs/Kconfig" 998source "fs/Kconfig"
999 999
1000menu "Instrumentation Support"
1001 depends on EXPERIMENTAL
1002
1000source "arch/i386/oprofile/Kconfig" 1003source "arch/i386/oprofile/Kconfig"
1001 1004
1005config KPROBES
1006 bool "Kprobes (EXPERIMENTAL)"
1007 help
1008 Kprobes allows you to trap at almost any kernel address and
1009 execute a callback function. register_kprobe() establishes
1010 a probepoint and specifies the callback. Kprobes is useful
1011 for kernel debugging, non-intrusive instrumentation and testing.
1012 If in doubt, say "N".
1013endmenu
1014
1002source "arch/i386/Kconfig.debug" 1015source "arch/i386/Kconfig.debug"
1003 1016
1004source "security/Kconfig" 1017source "security/Kconfig"
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index 5228c40a6fb2..c48b424dd640 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -22,16 +22,6 @@ config DEBUG_STACKOVERFLOW
22 This option will cause messages to be printed if free stack space 22 This option will cause messages to be printed if free stack space
23 drops below a certain limit. 23 drops below a certain limit.
24 24
25config KPROBES
26 bool "Kprobes"
27 depends on DEBUG_KERNEL
28 help
29 Kprobes allows you to trap at almost any kernel address and
30 execute a callback function. register_kprobe() establishes
31 a probepoint and specifies the callback. Kprobes is useful
32 for kernel debugging, non-intrusive instrumentation and testing.
33 If in doubt, say "N".
34
35config DEBUG_STACK_USAGE 25config DEBUG_STACK_USAGE
36 bool "Stack utilization instrumentation" 26 bool "Stack utilization instrumentation"
37 depends on DEBUG_KERNEL 27 depends on DEBUG_KERNEL
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 7c724ffa08bb..496a2c9909fe 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -559,14 +559,20 @@ void __devinit setup_local_APIC(void)
559 * If Linux enabled the LAPIC against the BIOS default 559 * If Linux enabled the LAPIC against the BIOS default
560 * disable it down before re-entering the BIOS on shutdown. 560 * disable it down before re-entering the BIOS on shutdown.
561 * Otherwise the BIOS may get confused and not power-off. 561 * Otherwise the BIOS may get confused and not power-off.
562 * Additionally clear all LVT entries before disable_local_APIC
563 * for the case where Linux didn't enable the LAPIC.
562 */ 564 */
563void lapic_shutdown(void) 565void lapic_shutdown(void)
564{ 566{
565 if (!cpu_has_apic || !enabled_via_apicbase) 567 if (!cpu_has_apic)
566 return; 568 return;
567 569
568 local_irq_disable(); 570 local_irq_disable();
569 disable_local_APIC(); 571 clear_local_APIC();
572
573 if (enabled_via_apicbase)
574 disable_local_APIC();
575
570 local_irq_enable(); 576 local_irq_enable();
571} 577}
572 578
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index d2ef0c2aa93e..86e80c551478 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -447,8 +447,7 @@ static char * apm_event_name[] = {
447 "system standby resume", 447 "system standby resume",
448 "capabilities change" 448 "capabilities change"
449}; 449};
450#define NR_APM_EVENT_NAME \ 450#define NR_APM_EVENT_NAME ARRAY_SIZE(apm_event_name)
451 (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
452 451
453typedef struct lookup_t { 452typedef struct lookup_t {
454 int key; 453 int key;
@@ -479,7 +478,7 @@ static const lookup_t error_table[] = {
479 { APM_NO_ERROR, "BIOS did not set a return code" }, 478 { APM_NO_ERROR, "BIOS did not set a return code" },
480 { APM_NOT_PRESENT, "No APM present" } 479 { APM_NOT_PRESENT, "No APM present" }
481}; 480};
482#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t)) 481#define ERROR_COUNT ARRAY_SIZE(error_table)
483 482
484/** 483/**
485 * apm_error - display an APM error 484 * apm_error - display an APM error
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 74145a33cb0f..c145fb30002e 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -30,8 +30,6 @@ static int disable_x86_serial_nr __devinitdata = 1;
30 30
31struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; 31struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
32 32
33extern void mcheck_init(struct cpuinfo_x86 *c);
34
35extern int disable_pse; 33extern int disable_pse;
36 34
37static void default_init(struct cpuinfo_x86 * c) 35static void default_init(struct cpuinfo_x86 * c)
@@ -429,9 +427,8 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
429 } 427 }
430 428
431 /* Init Machine Check Exception if available. */ 429 /* Init Machine Check Exception if available. */
432#ifdef CONFIG_X86_MCE
433 mcheck_init(c); 430 mcheck_init(c);
434#endif 431
435 if (c == &boot_cpu_data) 432 if (c == &boot_cpu_data)
436 sysenter_setup(); 433 sysenter_setup();
437 enable_sep_cpu(); 434 enable_sep_cpu();
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 1465974256c9..0ea010a7afb1 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -67,7 +67,7 @@ static const struct cpu_id cpu_ids[] = {
67 [CPU_MP4HT_D0] = {15, 3, 4 }, 67 [CPU_MP4HT_D0] = {15, 3, 4 },
68 [CPU_MP4HT_E0] = {15, 4, 1 }, 68 [CPU_MP4HT_E0] = {15, 4, 1 },
69}; 69};
70#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) 70#define N_IDS ARRAY_SIZE(cpu_ids)
71 71
72struct cpu_model 72struct cpu_model
73{ 73{
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c
index 7c6b9c73522f..fc5d5215e23d 100644
--- a/arch/i386/kernel/cpu/mcheck/k7.c
+++ b/arch/i386/kernel/cpu/mcheck/k7.c
@@ -68,7 +68,7 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code)
68 68
69 69
70/* AMD K7 machine check is Intel like */ 70/* AMD K7 machine check is Intel like */
71void __devinit amd_mcheck_init(struct cpuinfo_x86 *c) 71void amd_mcheck_init(struct cpuinfo_x86 *c)
72{ 72{
73 u32 l, h; 73 u32 l, h;
74 int i; 74 int i;
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index 2cf25d2ba0f1..6170af3c271a 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -16,7 +16,7 @@
16 16
17#include "mce.h" 17#include "mce.h"
18 18
19int mce_disabled __devinitdata = 0; 19int mce_disabled = 0;
20int nr_mce_banks; 20int nr_mce_banks;
21 21
22EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ 22EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_
31void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; 31void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
32 32
33/* This has to be run for each processor */ 33/* This has to be run for each processor */
34void __devinit mcheck_init(struct cpuinfo_x86 *c) 34void mcheck_init(struct cpuinfo_x86 *c)
35{ 35{
36 if (mce_disabled==1) 36 if (mce_disabled==1)
37 return; 37 return;
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index 1d1e885f500a..fd2c459a31ef 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -77,7 +77,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs)
77} 77}
78 78
79/* P4/Xeon Thermal regulation detect and init */ 79/* P4/Xeon Thermal regulation detect and init */
80static void __devinit intel_init_thermal(struct cpuinfo_x86 *c) 80static void intel_init_thermal(struct cpuinfo_x86 *c)
81{ 81{
82 u32 l, h; 82 u32 l, h;
83 unsigned int cpu = smp_processor_id(); 83 unsigned int cpu = smp_processor_id();
@@ -231,7 +231,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
231} 231}
232 232
233 233
234void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c) 234void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
235{ 235{
236 u32 l, h; 236 u32 l, h;
237 int i; 237 int i;
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c
index 3a2e24baddc7..94bc43d950cf 100644
--- a/arch/i386/kernel/cpu/mcheck/p5.c
+++ b/arch/i386/kernel/cpu/mcheck/p5.c
@@ -28,7 +28,7 @@ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_cod
28} 28}
29 29
30/* Set up machine check reporting for processors with Intel style MCE */ 30/* Set up machine check reporting for processors with Intel style MCE */
31void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c) 31void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
32{ 32{
33 u32 l, h; 33 u32 l, h;
34 34
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
index 979b18bc95c1..deeae42ce199 100644
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -79,7 +79,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
79} 79}
80 80
81/* Set up machine check reporting for processors with Intel style MCE */ 81/* Set up machine check reporting for processors with Intel style MCE */
82void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c) 82void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
83{ 83{
84 u32 l, h; 84 u32 l, h;
85 int i; 85 int i;
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c
index 5b9d2dd411d3..9e424b6c293d 100644
--- a/arch/i386/kernel/cpu/mcheck/winchip.c
+++ b/arch/i386/kernel/cpu/mcheck/winchip.c
@@ -22,7 +22,7 @@ static fastcall void winchip_machine_check(struct pt_regs * regs, long error_cod
22} 22}
23 23
24/* Set up machine check reporting on the Winchip C6 series */ 24/* Set up machine check reporting on the Winchip C6 series */
25void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c) 25void winchip_mcheck_init(struct cpuinfo_x86 *c)
26{ 26{
27 u32 lo, hi; 27 u32 lo, hi;
28 machine_check_vector = winchip_machine_check; 28 machine_check_vector = winchip_machine_check;
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 6345b430b105..32b0c24ab9a6 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -31,22 +31,16 @@
31#include <linux/config.h> 31#include <linux/config.h>
32#include <linux/kprobes.h> 32#include <linux/kprobes.h>
33#include <linux/ptrace.h> 33#include <linux/ptrace.h>
34#include <linux/spinlock.h>
35#include <linux/preempt.h> 34#include <linux/preempt.h>
36#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
37#include <asm/kdebug.h> 36#include <asm/kdebug.h>
38#include <asm/desc.h> 37#include <asm/desc.h>
39 38
40static struct kprobe *current_kprobe;
41static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
42static struct kprobe *kprobe_prev;
43static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
44static struct pt_regs jprobe_saved_regs;
45static long *jprobe_saved_esp;
46/* copy of the kernel stack at the probe fire time */
47static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
48void jprobe_return_end(void); 39void jprobe_return_end(void);
49 40
41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43
50/* 44/*
51 * returns non-zero if opcode modifies the interrupt flag. 45 * returns non-zero if opcode modifies the interrupt flag.
52 */ 46 */
@@ -91,29 +85,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
91{ 85{
92} 86}
93 87
94static inline void save_previous_kprobe(void) 88static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
95{ 89{
96 kprobe_prev = current_kprobe; 90 kcb->prev_kprobe.kp = kprobe_running();
97 kprobe_status_prev = kprobe_status; 91 kcb->prev_kprobe.status = kcb->kprobe_status;
98 kprobe_old_eflags_prev = kprobe_old_eflags; 92 kcb->prev_kprobe.old_eflags = kcb->kprobe_old_eflags;
99 kprobe_saved_eflags_prev = kprobe_saved_eflags; 93 kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
100} 94}
101 95
102static inline void restore_previous_kprobe(void) 96static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
103{ 97{
104 current_kprobe = kprobe_prev; 98 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
105 kprobe_status = kprobe_status_prev; 99 kcb->kprobe_status = kcb->prev_kprobe.status;
106 kprobe_old_eflags = kprobe_old_eflags_prev; 100 kcb->kprobe_old_eflags = kcb->prev_kprobe.old_eflags;
107 kprobe_saved_eflags = kprobe_saved_eflags_prev; 101 kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
108} 102}
109 103
110static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs) 104static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
105 struct kprobe_ctlblk *kcb)
111{ 106{
112 current_kprobe = p; 107 __get_cpu_var(current_kprobe) = p;
113 kprobe_saved_eflags = kprobe_old_eflags 108 kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
114 = (regs->eflags & (TF_MASK | IF_MASK)); 109 = (regs->eflags & (TF_MASK | IF_MASK));
115 if (is_IF_modifier(p->opcode)) 110 if (is_IF_modifier(p->opcode))
116 kprobe_saved_eflags &= ~IF_MASK; 111 kcb->kprobe_saved_eflags &= ~IF_MASK;
117} 112}
118 113
119static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 114static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -127,6 +122,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
127 regs->eip = (unsigned long)&p->ainsn.insn; 122 regs->eip = (unsigned long)&p->ainsn.insn;
128} 123}
129 124
125/* Called with kretprobe_lock held */
130void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, 126void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
131 struct pt_regs *regs) 127 struct pt_regs *regs)
132{ 128{
@@ -157,9 +153,15 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
157 int ret = 0; 153 int ret = 0;
158 kprobe_opcode_t *addr = NULL; 154 kprobe_opcode_t *addr = NULL;
159 unsigned long *lp; 155 unsigned long *lp;
156 struct kprobe_ctlblk *kcb;
160 157
161 /* We're in an interrupt, but this is clear and BUG()-safe. */ 158 /*
159 * We don't want to be preempted for the entire
160 * duration of kprobe processing
161 */
162 preempt_disable(); 162 preempt_disable();
163 kcb = get_kprobe_ctlblk();
164
163 /* Check if the application is using LDT entry for its code segment and 165 /* Check if the application is using LDT entry for its code segment and
164 * calculate the address by reading the base address from the LDT entry. 166 * calculate the address by reading the base address from the LDT entry.
165 */ 167 */
@@ -173,15 +175,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
173 } 175 }
174 /* Check we're not actually recursing */ 176 /* Check we're not actually recursing */
175 if (kprobe_running()) { 177 if (kprobe_running()) {
176 /* We *are* holding lock here, so this is safe.
177 Disarm the probe we just hit, and ignore it. */
178 p = get_kprobe(addr); 178 p = get_kprobe(addr);
179 if (p) { 179 if (p) {
180 if (kprobe_status == KPROBE_HIT_SS && 180 if (kcb->kprobe_status == KPROBE_HIT_SS &&
181 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { 181 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
182 regs->eflags &= ~TF_MASK; 182 regs->eflags &= ~TF_MASK;
183 regs->eflags |= kprobe_saved_eflags; 183 regs->eflags |= kcb->kprobe_saved_eflags;
184 unlock_kprobes();
185 goto no_kprobe; 184 goto no_kprobe;
186 } 185 }
187 /* We have reentered the kprobe_handler(), since 186 /* We have reentered the kprobe_handler(), since
@@ -190,26 +189,23 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
190 * just single step on the instruction of the new probe 189 * just single step on the instruction of the new probe
191 * without calling any user handlers. 190 * without calling any user handlers.
192 */ 191 */
193 save_previous_kprobe(); 192 save_previous_kprobe(kcb);
194 set_current_kprobe(p, regs); 193 set_current_kprobe(p, regs, kcb);
195 p->nmissed++; 194 p->nmissed++;
196 prepare_singlestep(p, regs); 195 prepare_singlestep(p, regs);
197 kprobe_status = KPROBE_REENTER; 196 kcb->kprobe_status = KPROBE_REENTER;
198 return 1; 197 return 1;
199 } else { 198 } else {
200 p = current_kprobe; 199 p = __get_cpu_var(current_kprobe);
201 if (p->break_handler && p->break_handler(p, regs)) { 200 if (p->break_handler && p->break_handler(p, regs)) {
202 goto ss_probe; 201 goto ss_probe;
203 } 202 }
204 } 203 }
205 /* If it's not ours, can't be delete race, (we hold lock). */
206 goto no_kprobe; 204 goto no_kprobe;
207 } 205 }
208 206
209 lock_kprobes();
210 p = get_kprobe(addr); 207 p = get_kprobe(addr);
211 if (!p) { 208 if (!p) {
212 unlock_kprobes();
213 if (regs->eflags & VM_MASK) { 209 if (regs->eflags & VM_MASK) {
214 /* We are in virtual-8086 mode. Return 0 */ 210 /* We are in virtual-8086 mode. Return 0 */
215 goto no_kprobe; 211 goto no_kprobe;
@@ -232,8 +228,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
232 goto no_kprobe; 228 goto no_kprobe;
233 } 229 }
234 230
235 kprobe_status = KPROBE_HIT_ACTIVE; 231 set_current_kprobe(p, regs, kcb);
236 set_current_kprobe(p, regs); 232 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
237 233
238 if (p->pre_handler && p->pre_handler(p, regs)) 234 if (p->pre_handler && p->pre_handler(p, regs))
239 /* handler has already set things up, so skip ss setup */ 235 /* handler has already set things up, so skip ss setup */
@@ -241,7 +237,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
241 237
242ss_probe: 238ss_probe:
243 prepare_singlestep(p, regs); 239 prepare_singlestep(p, regs);
244 kprobe_status = KPROBE_HIT_SS; 240 kcb->kprobe_status = KPROBE_HIT_SS;
245 return 1; 241 return 1;
246 242
247no_kprobe: 243no_kprobe:
@@ -269,9 +265,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
269 struct kretprobe_instance *ri = NULL; 265 struct kretprobe_instance *ri = NULL;
270 struct hlist_head *head; 266 struct hlist_head *head;
271 struct hlist_node *node, *tmp; 267 struct hlist_node *node, *tmp;
272 unsigned long orig_ret_address = 0; 268 unsigned long flags, orig_ret_address = 0;
273 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; 269 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
274 270
271 spin_lock_irqsave(&kretprobe_lock, flags);
275 head = kretprobe_inst_table_head(current); 272 head = kretprobe_inst_table_head(current);
276 273
277 /* 274 /*
@@ -310,14 +307,15 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
310 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); 307 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
311 regs->eip = orig_ret_address; 308 regs->eip = orig_ret_address;
312 309
313 unlock_kprobes(); 310 reset_current_kprobe();
311 spin_unlock_irqrestore(&kretprobe_lock, flags);
314 preempt_enable_no_resched(); 312 preempt_enable_no_resched();
315 313
316 /* 314 /*
317 * By returning a non-zero value, we are telling 315 * By returning a non-zero value, we are telling
318 * kprobe_handler() that we have handled unlocking 316 * kprobe_handler() that we don't want the post_handler
319 * and re-enabling preemption. 317 * to run (and have re-enabled preemption)
320 */ 318 */
321 return 1; 319 return 1;
322} 320}
323 321
@@ -343,7 +341,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
343 * that is atop the stack is the address following the copied instruction. 341 * that is atop the stack is the address following the copied instruction.
344 * We need to make it the address following the original instruction. 342 * We need to make it the address following the original instruction.
345 */ 343 */
346static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) 344static void __kprobes resume_execution(struct kprobe *p,
345 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
347{ 346{
348 unsigned long *tos = (unsigned long *)&regs->esp; 347 unsigned long *tos = (unsigned long *)&regs->esp;
349 unsigned long next_eip = 0; 348 unsigned long next_eip = 0;
@@ -353,7 +352,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
353 switch (p->ainsn.insn[0]) { 352 switch (p->ainsn.insn[0]) {
354 case 0x9c: /* pushfl */ 353 case 0x9c: /* pushfl */
355 *tos &= ~(TF_MASK | IF_MASK); 354 *tos &= ~(TF_MASK | IF_MASK);
356 *tos |= kprobe_old_eflags; 355 *tos |= kcb->kprobe_old_eflags;
357 break; 356 break;
358 case 0xc3: /* ret/lret */ 357 case 0xc3: /* ret/lret */
359 case 0xcb: 358 case 0xcb:
@@ -394,27 +393,30 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
394 393
395/* 394/*
396 * Interrupts are disabled on entry as trap1 is an interrupt gate and they 395 * Interrupts are disabled on entry as trap1 is an interrupt gate and they
397 * remain disabled thoroughout this function. And we hold kprobe lock. 396 * remain disabled thoroughout this function.
398 */ 397 */
399static inline int post_kprobe_handler(struct pt_regs *regs) 398static inline int post_kprobe_handler(struct pt_regs *regs)
400{ 399{
401 if (!kprobe_running()) 400 struct kprobe *cur = kprobe_running();
401 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
402
403 if (!cur)
402 return 0; 404 return 0;
403 405
404 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { 406 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
405 kprobe_status = KPROBE_HIT_SSDONE; 407 kcb->kprobe_status = KPROBE_HIT_SSDONE;
406 current_kprobe->post_handler(current_kprobe, regs, 0); 408 cur->post_handler(cur, regs, 0);
407 } 409 }
408 410
409 resume_execution(current_kprobe, regs); 411 resume_execution(cur, regs, kcb);
410 regs->eflags |= kprobe_saved_eflags; 412 regs->eflags |= kcb->kprobe_saved_eflags;
411 413
412 /*Restore back the original saved kprobes variables and continue. */ 414 /*Restore back the original saved kprobes variables and continue. */
413 if (kprobe_status == KPROBE_REENTER) { 415 if (kcb->kprobe_status == KPROBE_REENTER) {
414 restore_previous_kprobe(); 416 restore_previous_kprobe(kcb);
415 goto out; 417 goto out;
416 } 418 }
417 unlock_kprobes(); 419 reset_current_kprobe();
418out: 420out:
419 preempt_enable_no_resched(); 421 preempt_enable_no_resched();
420 422
@@ -429,18 +431,19 @@ out:
429 return 1; 431 return 1;
430} 432}
431 433
432/* Interrupts disabled, kprobe_lock held. */
433static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 434static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
434{ 435{
435 if (current_kprobe->fault_handler 436 struct kprobe *cur = kprobe_running();
436 && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) 437 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
438
439 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
437 return 1; 440 return 1;
438 441
439 if (kprobe_status & KPROBE_HIT_SS) { 442 if (kcb->kprobe_status & KPROBE_HIT_SS) {
440 resume_execution(current_kprobe, regs); 443 resume_execution(cur, regs, kcb);
441 regs->eflags |= kprobe_old_eflags; 444 regs->eflags |= kcb->kprobe_old_eflags;
442 445
443 unlock_kprobes(); 446 reset_current_kprobe();
444 preempt_enable_no_resched(); 447 preempt_enable_no_resched();
445 } 448 }
446 return 0; 449 return 0;
@@ -453,39 +456,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
453 unsigned long val, void *data) 456 unsigned long val, void *data)
454{ 457{
455 struct die_args *args = (struct die_args *)data; 458 struct die_args *args = (struct die_args *)data;
459 int ret = NOTIFY_DONE;
460
456 switch (val) { 461 switch (val) {
457 case DIE_INT3: 462 case DIE_INT3:
458 if (kprobe_handler(args->regs)) 463 if (kprobe_handler(args->regs))
459 return NOTIFY_STOP; 464 ret = NOTIFY_STOP;
460 break; 465 break;
461 case DIE_DEBUG: 466 case DIE_DEBUG:
462 if (post_kprobe_handler(args->regs)) 467 if (post_kprobe_handler(args->regs))
463 return NOTIFY_STOP; 468 ret = NOTIFY_STOP;
464 break; 469 break;
465 case DIE_GPF: 470 case DIE_GPF:
466 if (kprobe_running() &&
467 kprobe_fault_handler(args->regs, args->trapnr))
468 return NOTIFY_STOP;
469 break;
470 case DIE_PAGE_FAULT: 471 case DIE_PAGE_FAULT:
472 /* kprobe_running() needs smp_processor_id() */
473 preempt_disable();
471 if (kprobe_running() && 474 if (kprobe_running() &&
472 kprobe_fault_handler(args->regs, args->trapnr)) 475 kprobe_fault_handler(args->regs, args->trapnr))
473 return NOTIFY_STOP; 476 ret = NOTIFY_STOP;
477 preempt_enable();
474 break; 478 break;
475 default: 479 default:
476 break; 480 break;
477 } 481 }
478 return NOTIFY_DONE; 482 return ret;
479} 483}
480 484
481int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 485int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
482{ 486{
483 struct jprobe *jp = container_of(p, struct jprobe, kp); 487 struct jprobe *jp = container_of(p, struct jprobe, kp);
484 unsigned long addr; 488 unsigned long addr;
489 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
485 490
486 jprobe_saved_regs = *regs; 491 kcb->jprobe_saved_regs = *regs;
487 jprobe_saved_esp = &regs->esp; 492 kcb->jprobe_saved_esp = &regs->esp;
488 addr = (unsigned long)jprobe_saved_esp; 493 addr = (unsigned long)(kcb->jprobe_saved_esp);
489 494
490 /* 495 /*
491 * TBD: As Linus pointed out, gcc assumes that the callee 496 * TBD: As Linus pointed out, gcc assumes that the callee
@@ -494,7 +499,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
494 * we also save and restore enough stack bytes to cover 499 * we also save and restore enough stack bytes to cover
495 * the argument area. 500 * the argument area.
496 */ 501 */
497 memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr)); 502 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
503 MIN_STACK_SIZE(addr));
498 regs->eflags &= ~IF_MASK; 504 regs->eflags &= ~IF_MASK;
499 regs->eip = (unsigned long)(jp->entry); 505 regs->eip = (unsigned long)(jp->entry);
500 return 1; 506 return 1;
@@ -502,36 +508,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
502 508
503void __kprobes jprobe_return(void) 509void __kprobes jprobe_return(void)
504{ 510{
505 preempt_enable_no_resched(); 511 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
512
506 asm volatile (" xchgl %%ebx,%%esp \n" 513 asm volatile (" xchgl %%ebx,%%esp \n"
507 " int3 \n" 514 " int3 \n"
508 " .globl jprobe_return_end \n" 515 " .globl jprobe_return_end \n"
509 " jprobe_return_end: \n" 516 " jprobe_return_end: \n"
510 " nop \n"::"b" 517 " nop \n"::"b"
511 (jprobe_saved_esp):"memory"); 518 (kcb->jprobe_saved_esp):"memory");
512} 519}
513 520
514int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 521int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
515{ 522{
523 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
516 u8 *addr = (u8 *) (regs->eip - 1); 524 u8 *addr = (u8 *) (regs->eip - 1);
517 unsigned long stack_addr = (unsigned long)jprobe_saved_esp; 525 unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_esp);
518 struct jprobe *jp = container_of(p, struct jprobe, kp); 526 struct jprobe *jp = container_of(p, struct jprobe, kp);
519 527
520 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { 528 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
521 if (&regs->esp != jprobe_saved_esp) { 529 if (&regs->esp != kcb->jprobe_saved_esp) {
522 struct pt_regs *saved_regs = 530 struct pt_regs *saved_regs =
523 container_of(jprobe_saved_esp, struct pt_regs, esp); 531 container_of(kcb->jprobe_saved_esp,
532 struct pt_regs, esp);
524 printk("current esp %p does not match saved esp %p\n", 533 printk("current esp %p does not match saved esp %p\n",
525 &regs->esp, jprobe_saved_esp); 534 &regs->esp, kcb->jprobe_saved_esp);
526 printk("Saved registers for jprobe %p\n", jp); 535 printk("Saved registers for jprobe %p\n", jp);
527 show_registers(saved_regs); 536 show_registers(saved_regs);
528 printk("Current registers\n"); 537 printk("Current registers\n");
529 show_registers(regs); 538 show_registers(regs);
530 BUG(); 539 BUG();
531 } 540 }
532 *regs = jprobe_saved_regs; 541 *regs = kcb->jprobe_saved_regs;
533 memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack, 542 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
534 MIN_STACK_SIZE(stack_addr)); 543 MIN_STACK_SIZE(stack_addr));
544 preempt_enable_no_resched();
535 return 1; 545 return 1;
536 } 546 }
537 return 0; 547 return 0;
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index fe1ffa55587d..983f95707e11 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -18,6 +18,7 @@
18#include <asm/system.h> 18#include <asm/system.h>
19#include <asm/ldt.h> 19#include <asm/ldt.h>
20#include <asm/desc.h> 20#include <asm/desc.h>
21#include <asm/mmu_context.h>
21 22
22#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ 23#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
23static void flush_ldt(void *null) 24static void flush_ldt(void *null)
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index 8600faeea29d..558bb207720f 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -132,7 +132,7 @@ static struct resource mca_standard_resources[] = {
132 { .start = 0x100, .end = 0x107, .name = "POS (MCA)" } 132 { .start = 0x100, .end = 0x107, .name = "POS (MCA)" }
133}; 133};
134 134
135#define MCA_STANDARD_RESOURCES (sizeof(mca_standard_resources)/sizeof(struct resource)) 135#define MCA_STANDARD_RESOURCES ARRAY_SIZE(mca_standard_resources)
136 136
137/** 137/**
138 * mca_read_and_store_pos - read the POS registers into a memory buffer 138 * mca_read_and_store_pos - read the POS registers into a memory buffer
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index efd11f09c996..5ffbb4b7ad05 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -354,49 +354,12 @@ ptrace_set_thread_area(struct task_struct *child,
354 return 0; 354 return 0;
355} 355}
356 356
357asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 357long arch_ptrace(struct task_struct *child, long request, long addr, long data)
358{ 358{
359 struct task_struct *child;
360 struct user * dummy = NULL; 359 struct user * dummy = NULL;
361 int i, ret; 360 int i, ret;
362 unsigned long __user *datap = (unsigned long __user *)data; 361 unsigned long __user *datap = (unsigned long __user *)data;
363 362
364 lock_kernel();
365 ret = -EPERM;
366 if (request == PTRACE_TRACEME) {
367 /* are we already being traced? */
368 if (current->ptrace & PT_PTRACED)
369 goto out;
370 ret = security_ptrace(current->parent, current);
371 if (ret)
372 goto out;
373 /* set the ptrace bit in the process flags. */
374 current->ptrace |= PT_PTRACED;
375 ret = 0;
376 goto out;
377 }
378 ret = -ESRCH;
379 read_lock(&tasklist_lock);
380 child = find_task_by_pid(pid);
381 if (child)
382 get_task_struct(child);
383 read_unlock(&tasklist_lock);
384 if (!child)
385 goto out;
386
387 ret = -EPERM;
388 if (pid == 1) /* you may not mess with init */
389 goto out_tsk;
390
391 if (request == PTRACE_ATTACH) {
392 ret = ptrace_attach(child);
393 goto out_tsk;
394 }
395
396 ret = ptrace_check_attach(child, request == PTRACE_KILL);
397 if (ret < 0)
398 goto out_tsk;
399
400 switch (request) { 363 switch (request) {
401 /* when I and D space are separate, these will need to be fixed. */ 364 /* when I and D space are separate, these will need to be fixed. */
402 case PTRACE_PEEKTEXT: /* read word at location addr. */ 365 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -663,10 +626,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
663 ret = ptrace_request(child, request, addr, data); 626 ret = ptrace_request(child, request, addr, data);
664 break; 627 break;
665 } 628 }
666out_tsk: 629 out_tsk:
667 put_task_struct(child);
668out:
669 unlock_kernel();
670 return ret; 630 return ret;
671} 631}
672 632
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
index c9b87330aeea..10e21a4773dd 100644
--- a/arch/i386/kernel/reboot_fixups.c
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -10,6 +10,7 @@
10 10
11#include <asm/delay.h> 11#include <asm/delay.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/reboot_fixups.h>
13 14
14static void cs5530a_warm_reset(struct pci_dev *dev) 15static void cs5530a_warm_reset(struct pci_dev *dev)
15{ 16{
@@ -42,7 +43,7 @@ void mach_reboot_fixups(void)
42 struct pci_dev *dev; 43 struct pci_dev *dev;
43 int i; 44 int i;
44 45
45 for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) { 46 for (i=0; i < ARRAY_SIZE(fixups_table); i++) {
46 cur = &(fixups_table[i]); 47 cur = &(fixups_table[i]);
47 dev = pci_get_device(cur->vendor, cur->device, NULL); 48 dev = pci_get_device(cur->vendor, cur->device, NULL);
48 if (!dev) 49 if (!dev)
diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c
index 69e203a0d330..9c968ae67c43 100644
--- a/arch/i386/kernel/scx200.c
+++ b/arch/i386/kernel/scx200.c
@@ -12,6 +12,7 @@
12#include <linux/pci.h> 12#include <linux/pci.h>
13 13
14#include <linux/scx200.h> 14#include <linux/scx200.h>
15#include <linux/scx200_gpio.h>
15 16
16/* Verify that the configuration block really is there */ 17/* Verify that the configuration block really is there */
17#define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base)) 18#define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 01b618e73ecd..47ec76794d02 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -68,11 +68,9 @@ EXPORT_SYMBOL(smp_num_siblings);
68 68
69/* Package ID of each logical CPU */ 69/* Package ID of each logical CPU */
70int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; 70int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
71EXPORT_SYMBOL(phys_proc_id);
72 71
73/* Core ID of each logical CPU */ 72/* Core ID of each logical CPU */
74int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; 73int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
75EXPORT_SYMBOL(cpu_core_id);
76 74
77cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; 75cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
78EXPORT_SYMBOL(cpu_sibling_map); 76EXPORT_SYMBOL(cpu_sibling_map);
@@ -612,7 +610,7 @@ static inline void __inquire_remote_apic(int apicid)
612 610
613 printk("Inquiring remote APIC #%d...\n", apicid); 611 printk("Inquiring remote APIC #%d...\n", apicid);
614 612
615 for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) { 613 for (i = 0; i < ARRAY_SIZE(regs); i++) {
616 printk("... APIC #%d %s: ", apicid, names[i]); 614 printk("... APIC #%d %s: ", apicid, names[i]);
617 615
618 /* 616 /*
diff --git a/arch/i386/oprofile/Kconfig b/arch/i386/oprofile/Kconfig
index 5ade19801b97..d8a84088471a 100644
--- a/arch/i386/oprofile/Kconfig
+++ b/arch/i386/oprofile/Kconfig
@@ -1,7 +1,3 @@
1
2menu "Profiling support"
3 depends on EXPERIMENTAL
4
5config PROFILING 1config PROFILING
6 bool "Profiling support (EXPERIMENTAL)" 2 bool "Profiling support (EXPERIMENTAL)"
7 help 3 help
@@ -19,5 +15,3 @@ config OPROFILE
19 15
20 If unsure, say N. 16 If unsure, say N.
21 17
22endmenu
23
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index 1f1572692e0b..50a0bef8c85f 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -118,6 +118,7 @@ void __restore_processor_state(struct saved_context *ctxt)
118 fix_processor_context(); 118 fix_processor_context();
119 do_fpu_end(); 119 do_fpu_end();
120 mtrr_ap_init(); 120 mtrr_ap_init();
121 mcheck_init(&boot_cpu_data);
121} 122}
122 123
123void restore_processor_state(void) 124void restore_processor_state(void)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 3b4248cff9a7..9f2093c1f44b 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -426,8 +426,21 @@ config GENERIC_PENDING_IRQ
426 426
427source "arch/ia64/hp/sim/Kconfig" 427source "arch/ia64/hp/sim/Kconfig"
428 428
429menu "Instrumentation Support"
430 depends on EXPERIMENTAL
431
429source "arch/ia64/oprofile/Kconfig" 432source "arch/ia64/oprofile/Kconfig"
430 433
434config KPROBES
435 bool "Kprobes (EXPERIMENTAL)"
436 help
437 Kprobes allows you to trap at almost any kernel address and
438 execute a callback function. register_kprobe() establishes
439 a probepoint and specifies the callback. Kprobes is useful
440 for kernel debugging, non-intrusive instrumentation and testing.
441 If in doubt, say "N".
442endmenu
443
431source "arch/ia64/Kconfig.debug" 444source "arch/ia64/Kconfig.debug"
432 445
433source "security/Kconfig" 446source "security/Kconfig"
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
index fda67ac993d7..de9d507ba0fd 100644
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -2,17 +2,6 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config KPROBES
6 bool "Kprobes"
7 depends on DEBUG_KERNEL
8 help
9 Kprobes allows you to trap at almost any kernel address and
10 execute a callback function. register_kprobe() establishes
11 a probepoint and specifies the callback. Kprobes is useful
12 for kernel debugging, non-intrusive instrumentation and testing.
13 If in doubt, say "N".
14
15
16choice 5choice
17 prompt "Physical memory granularity" 6 prompt "Physical memory granularity"
18 default IA64_GRANULE_64MB 7 default IA64_GRANULE_64MB
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index b42ec37be51c..19ee635eeb70 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -642,10 +642,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
642 info->event = 0; 642 info->event = 0;
643 info->tty = 0; 643 info->tty = 0;
644 if (info->blocked_open) { 644 if (info->blocked_open) {
645 if (info->close_delay) { 645 if (info->close_delay)
646 current->state = TASK_INTERRUPTIBLE; 646 schedule_timeout_interruptible(info->close_delay);
647 schedule_timeout(info->close_delay);
648 }
649 wake_up_interruptible(&info->open_wait); 647 wake_up_interruptible(&info->open_wait);
650 } 648 }
651 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 649 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 471086b808a4..96736a119c91 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -26,7 +26,6 @@
26#include <linux/config.h> 26#include <linux/config.h>
27#include <linux/kprobes.h> 27#include <linux/kprobes.h>
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/spinlock.h>
30#include <linux/string.h> 29#include <linux/string.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/preempt.h> 31#include <linux/preempt.h>
@@ -38,13 +37,8 @@
38 37
39extern void jprobe_inst_return(void); 38extern void jprobe_inst_return(void);
40 39
41/* kprobe_status settings */ 40DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42#define KPROBE_HIT_ACTIVE 0x00000001 41DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43#define KPROBE_HIT_SS 0x00000002
44
45static struct kprobe *current_kprobe, *kprobe_prev;
46static unsigned long kprobe_status, kprobe_status_prev;
47static struct pt_regs jprobe_saved_regs;
48 42
49enum instruction_type {A, I, M, F, B, L, X, u}; 43enum instruction_type {A, I, M, F, B, L, X, u};
50static enum instruction_type bundle_encoding[32][3] = { 44static enum instruction_type bundle_encoding[32][3] = {
@@ -313,21 +307,22 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
313 return 0; 307 return 0;
314} 308}
315 309
316static inline void save_previous_kprobe(void) 310static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
317{ 311{
318 kprobe_prev = current_kprobe; 312 kcb->prev_kprobe.kp = kprobe_running();
319 kprobe_status_prev = kprobe_status; 313 kcb->prev_kprobe.status = kcb->kprobe_status;
320} 314}
321 315
322static inline void restore_previous_kprobe(void) 316static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
323{ 317{
324 current_kprobe = kprobe_prev; 318 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
325 kprobe_status = kprobe_status_prev; 319 kcb->kprobe_status = kcb->prev_kprobe.status;
326} 320}
327 321
328static inline void set_current_kprobe(struct kprobe *p) 322static inline void set_current_kprobe(struct kprobe *p,
323 struct kprobe_ctlblk *kcb)
329{ 324{
330 current_kprobe = p; 325 __get_cpu_var(current_kprobe) = p;
331} 326}
332 327
333static void kretprobe_trampoline(void) 328static void kretprobe_trampoline(void)
@@ -347,10 +342,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
347 struct kretprobe_instance *ri = NULL; 342 struct kretprobe_instance *ri = NULL;
348 struct hlist_head *head; 343 struct hlist_head *head;
349 struct hlist_node *node, *tmp; 344 struct hlist_node *node, *tmp;
350 unsigned long orig_ret_address = 0; 345 unsigned long flags, orig_ret_address = 0;
351 unsigned long trampoline_address = 346 unsigned long trampoline_address =
352 ((struct fnptr *)kretprobe_trampoline)->ip; 347 ((struct fnptr *)kretprobe_trampoline)->ip;
353 348
349 spin_lock_irqsave(&kretprobe_lock, flags);
354 head = kretprobe_inst_table_head(current); 350 head = kretprobe_inst_table_head(current);
355 351
356 /* 352 /*
@@ -389,17 +385,19 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
389 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); 385 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
390 regs->cr_iip = orig_ret_address; 386 regs->cr_iip = orig_ret_address;
391 387
392 unlock_kprobes(); 388 reset_current_kprobe();
389 spin_unlock_irqrestore(&kretprobe_lock, flags);
393 preempt_enable_no_resched(); 390 preempt_enable_no_resched();
394 391
395 /* 392 /*
396 * By returning a non-zero value, we are telling 393 * By returning a non-zero value, we are telling
397 * kprobe_handler() that we have handled unlocking 394 * kprobe_handler() that we don't want the post_handler
398 * and re-enabling preemption. 395 * to run (and have re-enabled preemption)
399 */ 396 */
400 return 1; 397 return 1;
401} 398}
402 399
400/* Called with kretprobe_lock held */
403void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, 401void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
404 struct pt_regs *regs) 402 struct pt_regs *regs)
405{ 403{
@@ -606,17 +604,22 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
606 int ret = 0; 604 int ret = 0;
607 struct pt_regs *regs = args->regs; 605 struct pt_regs *regs = args->regs;
608 kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); 606 kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
607 struct kprobe_ctlblk *kcb;
609 608
609 /*
610 * We don't want to be preempted for the entire
611 * duration of kprobe processing
612 */
610 preempt_disable(); 613 preempt_disable();
614 kcb = get_kprobe_ctlblk();
611 615
612 /* Handle recursion cases */ 616 /* Handle recursion cases */
613 if (kprobe_running()) { 617 if (kprobe_running()) {
614 p = get_kprobe(addr); 618 p = get_kprobe(addr);
615 if (p) { 619 if (p) {
616 if ( (kprobe_status == KPROBE_HIT_SS) && 620 if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
617 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { 621 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
618 ia64_psr(regs)->ss = 0; 622 ia64_psr(regs)->ss = 0;
619 unlock_kprobes();
620 goto no_kprobe; 623 goto no_kprobe;
621 } 624 }
622 /* We have reentered the pre_kprobe_handler(), since 625 /* We have reentered the pre_kprobe_handler(), since
@@ -625,17 +628,17 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
625 * just single step on the instruction of the new probe 628 * just single step on the instruction of the new probe
626 * without calling any user handlers. 629 * without calling any user handlers.
627 */ 630 */
628 save_previous_kprobe(); 631 save_previous_kprobe(kcb);
629 set_current_kprobe(p); 632 set_current_kprobe(p, kcb);
630 p->nmissed++; 633 p->nmissed++;
631 prepare_ss(p, regs); 634 prepare_ss(p, regs);
632 kprobe_status = KPROBE_REENTER; 635 kcb->kprobe_status = KPROBE_REENTER;
633 return 1; 636 return 1;
634 } else if (args->err == __IA64_BREAK_JPROBE) { 637 } else if (args->err == __IA64_BREAK_JPROBE) {
635 /* 638 /*
636 * jprobe instrumented function just completed 639 * jprobe instrumented function just completed
637 */ 640 */
638 p = current_kprobe; 641 p = __get_cpu_var(current_kprobe);
639 if (p->break_handler && p->break_handler(p, regs)) { 642 if (p->break_handler && p->break_handler(p, regs)) {
640 goto ss_probe; 643 goto ss_probe;
641 } 644 }
@@ -645,10 +648,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
645 } 648 }
646 } 649 }
647 650
648 lock_kprobes();
649 p = get_kprobe(addr); 651 p = get_kprobe(addr);
650 if (!p) { 652 if (!p) {
651 unlock_kprobes();
652 if (!is_ia64_break_inst(regs)) { 653 if (!is_ia64_break_inst(regs)) {
653 /* 654 /*
654 * The breakpoint instruction was removed right 655 * The breakpoint instruction was removed right
@@ -665,8 +666,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
665 goto no_kprobe; 666 goto no_kprobe;
666 } 667 }
667 668
668 kprobe_status = KPROBE_HIT_ACTIVE; 669 set_current_kprobe(p, kcb);
669 set_current_kprobe(p); 670 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
670 671
671 if (p->pre_handler && p->pre_handler(p, regs)) 672 if (p->pre_handler && p->pre_handler(p, regs))
672 /* 673 /*
@@ -678,7 +679,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
678 679
679ss_probe: 680ss_probe:
680 prepare_ss(p, regs); 681 prepare_ss(p, regs);
681 kprobe_status = KPROBE_HIT_SS; 682 kcb->kprobe_status = KPROBE_HIT_SS;
682 return 1; 683 return 1;
683 684
684no_kprobe: 685no_kprobe:
@@ -688,23 +689,25 @@ no_kprobe:
688 689
689static int __kprobes post_kprobes_handler(struct pt_regs *regs) 690static int __kprobes post_kprobes_handler(struct pt_regs *regs)
690{ 691{
691 if (!kprobe_running()) 692 struct kprobe *cur = kprobe_running();
693 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
694
695 if (!cur)
692 return 0; 696 return 0;
693 697
694 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { 698 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
695 kprobe_status = KPROBE_HIT_SSDONE; 699 kcb->kprobe_status = KPROBE_HIT_SSDONE;
696 current_kprobe->post_handler(current_kprobe, regs, 0); 700 cur->post_handler(cur, regs, 0);
697 } 701 }
698 702
699 resume_execution(current_kprobe, regs); 703 resume_execution(cur, regs);
700 704
701 /*Restore back the original saved kprobes variables and continue. */ 705 /*Restore back the original saved kprobes variables and continue. */
702 if (kprobe_status == KPROBE_REENTER) { 706 if (kcb->kprobe_status == KPROBE_REENTER) {
703 restore_previous_kprobe(); 707 restore_previous_kprobe(kcb);
704 goto out; 708 goto out;
705 } 709 }
706 710 reset_current_kprobe();
707 unlock_kprobes();
708 711
709out: 712out:
710 preempt_enable_no_resched(); 713 preempt_enable_no_resched();
@@ -713,16 +716,15 @@ out:
713 716
714static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) 717static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
715{ 718{
716 if (!kprobe_running()) 719 struct kprobe *cur = kprobe_running();
717 return 0; 720 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
718 721
719 if (current_kprobe->fault_handler && 722 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
720 current_kprobe->fault_handler(current_kprobe, regs, trapnr))
721 return 1; 723 return 1;
722 724
723 if (kprobe_status & KPROBE_HIT_SS) { 725 if (kcb->kprobe_status & KPROBE_HIT_SS) {
724 resume_execution(current_kprobe, regs); 726 resume_execution(cur, regs);
725 unlock_kprobes(); 727 reset_current_kprobe();
726 preempt_enable_no_resched(); 728 preempt_enable_no_resched();
727 } 729 }
728 730
@@ -733,31 +735,38 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
733 unsigned long val, void *data) 735 unsigned long val, void *data)
734{ 736{
735 struct die_args *args = (struct die_args *)data; 737 struct die_args *args = (struct die_args *)data;
738 int ret = NOTIFY_DONE;
739
736 switch(val) { 740 switch(val) {
737 case DIE_BREAK: 741 case DIE_BREAK:
738 if (pre_kprobes_handler(args)) 742 if (pre_kprobes_handler(args))
739 return NOTIFY_STOP; 743 ret = NOTIFY_STOP;
740 break; 744 break;
741 case DIE_SS: 745 case DIE_SS:
742 if (post_kprobes_handler(args->regs)) 746 if (post_kprobes_handler(args->regs))
743 return NOTIFY_STOP; 747 ret = NOTIFY_STOP;
744 break; 748 break;
745 case DIE_PAGE_FAULT: 749 case DIE_PAGE_FAULT:
746 if (kprobes_fault_handler(args->regs, args->trapnr)) 750 /* kprobe_running() needs smp_processor_id() */
747 return NOTIFY_STOP; 751 preempt_disable();
752 if (kprobe_running() &&
753 kprobes_fault_handler(args->regs, args->trapnr))
754 ret = NOTIFY_STOP;
755 preempt_enable();
748 default: 756 default:
749 break; 757 break;
750 } 758 }
751 return NOTIFY_DONE; 759 return ret;
752} 760}
753 761
754int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 762int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
755{ 763{
756 struct jprobe *jp = container_of(p, struct jprobe, kp); 764 struct jprobe *jp = container_of(p, struct jprobe, kp);
757 unsigned long addr = ((struct fnptr *)(jp->entry))->ip; 765 unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
766 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
758 767
759 /* save architectural state */ 768 /* save architectural state */
760 jprobe_saved_regs = *regs; 769 kcb->jprobe_saved_regs = *regs;
761 770
762 /* after rfi, execute the jprobe instrumented function */ 771 /* after rfi, execute the jprobe instrumented function */
763 regs->cr_iip = addr & ~0xFULL; 772 regs->cr_iip = addr & ~0xFULL;
@@ -775,7 +784,10 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
775 784
776int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 785int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
777{ 786{
778 *regs = jprobe_saved_regs; 787 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
788
789 *regs = kcb->jprobe_saved_regs;
790 preempt_enable_no_resched();
779 return 1; 791 return 1;
780} 792}
781 793
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f7dfc107cb7b..410d4804fa6e 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -4940,7 +4940,7 @@ abort_locked:
4940 if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; 4940 if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
4941 4941
4942error_args: 4942error_args:
4943 if (args_k) kfree(args_k); 4943 kfree(args_k);
4944 4944
4945 DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret)); 4945 DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret));
4946 4946
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index fc56ca2da358..3af6de36a482 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -92,6 +92,13 @@ extern void efi_initialize_iomem_resources(struct resource *,
92extern char _text[], _end[], _etext[]; 92extern char _text[], _end[], _etext[];
93 93
94unsigned long ia64_max_cacheline_size; 94unsigned long ia64_max_cacheline_size;
95
96int dma_get_cache_alignment(void)
97{
98 return ia64_max_cacheline_size;
99}
100EXPORT_SYMBOL(dma_get_cache_alignment);
101
95unsigned long ia64_iobase; /* virtual address for I/O accesses */ 102unsigned long ia64_iobase; /* virtual address for I/O accesses */
96EXPORT_SYMBOL(ia64_iobase); 103EXPORT_SYMBOL(ia64_iobase);
97struct io_space io_space[MAX_IO_SPACES]; 104struct io_space io_space[MAX_IO_SPACES];
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
index 56e6f614b04a..97271ab484dc 100644
--- a/arch/ia64/oprofile/Kconfig
+++ b/arch/ia64/oprofile/Kconfig
@@ -1,7 +1,3 @@
1
2menu "Profiling support"
3 depends on EXPERIMENTAL
4
5config PROFILING 1config PROFILING
6 bool "Profiling support (EXPERIMENTAL)" 2 bool "Profiling support (EXPERIMENTAL)"
7 help 3 help
@@ -22,5 +18,3 @@ config OPROFILE
22 18
23 If unsure, say N. 19 If unsure, say N.
24 20
25endmenu
26
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 6df7fb60dfea..e79bbc94216d 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -212,10 +212,8 @@ int atari_tt_hwclk( int op, struct rtc_time *t )
212 * additionally the RTC_SET bit is set to prevent an update cycle. 212 * additionally the RTC_SET bit is set to prevent an update cycle.
213 */ 213 */
214 214
215 while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) { 215 while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP )
216 current->state = TASK_INTERRUPTIBLE; 216 schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
217 schedule_timeout(HWCLK_POLL_INTERVAL);
218 }
219 217
220 local_irq_save(flags); 218 local_irq_save(flags);
221 RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET ); 219 RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index f7f1d2e5b90b..7e54422685cf 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -121,48 +121,11 @@ void ptrace_disable(struct task_struct *child)
121 child->thread.work.syscall_trace = 0; 121 child->thread.work.syscall_trace = 0;
122} 122}
123 123
124asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 124long arch_ptrace(struct task_struct *child, long request, long addr, long data)
125{ 125{
126 struct task_struct *child;
127 unsigned long tmp; 126 unsigned long tmp;
128 int i, ret = 0; 127 int i, ret = 0;
129 128
130 lock_kernel();
131 if (request == PTRACE_TRACEME) {
132 /* are we already being traced? */
133 if (current->ptrace & PT_PTRACED) {
134 ret = -EPERM;
135 goto out;
136 }
137 /* set the ptrace bit in the process flags. */
138 current->ptrace |= PT_PTRACED;
139 goto out;
140 }
141 read_lock(&tasklist_lock);
142 child = find_task_by_pid(pid);
143 if (child)
144 get_task_struct(child);
145 read_unlock(&tasklist_lock);
146 if (unlikely(!child)) {
147 ret = -ESRCH;
148 goto out;
149 }
150
151 /* you may not mess with init */
152 if (unlikely(pid == 1)) {
153 ret = -EPERM;
154 goto out_tsk;
155 }
156
157 if (request == PTRACE_ATTACH) {
158 ret = ptrace_attach(child);
159 goto out_tsk;
160 }
161
162 ret = ptrace_check_attach(child, request == PTRACE_KILL);
163 if (ret)
164 goto out_tsk;
165
166 switch (request) { 129 switch (request) {
167 /* when I and D space are separate, these will need to be fixed. */ 130 /* when I and D space are separate, these will need to be fixed. */
168 case PTRACE_PEEKTEXT: /* read word at location addr. */ 131 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -317,14 +280,10 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
317 ret = ptrace_request(child, request, addr, data); 280 ret = ptrace_request(child, request, addr, data);
318 break; 281 break;
319 } 282 }
320out_tsk: 283
321 put_task_struct(child);
322out:
323 unlock_kernel();
324 return ret; 284 return ret;
325out_eio: 285out_eio:
326 ret = -EIO; 286 return -EIO;
327 goto out_tsk;
328} 287}
329 288
330asmlinkage void syscall_trace(void) 289asmlinkage void syscall_trace(void)
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 8520df9cee6d..b96498120fe9 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -71,6 +71,11 @@ config M5206e
71 help 71 help
72 Motorola ColdFire 5206e processor support. 72 Motorola ColdFire 5206e processor support.
73 73
74config M520x
75 bool "MCF520x"
76 help
77 Freescale Coldfire 5207/5208 processor support.
78
74config M523x 79config M523x
75 bool "MCF523x" 80 bool "MCF523x"
76 help 81 help
@@ -120,7 +125,7 @@ config M527x
120 125
121config COLDFIRE 126config COLDFIRE
122 bool 127 bool
123 depends on (M5206 || M5206e || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407) 128 depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
124 default y 129 default y
125 130
126choice 131choice
@@ -322,6 +327,12 @@ config ELITE
322 help 327 help
323 Support for the Motorola M5206eLITE board. 328 Support for the Motorola M5206eLITE board.
324 329
330config M5208EVB
331 bool "Freescale M5208EVB board support"
332 depends on M520x
333 help
334 Support for the Freescale Coldfire M5208EVB.
335
325config M5235EVB 336config M5235EVB
326 bool "Freescale M5235EVB support" 337 bool "Freescale M5235EVB support"
327 depends on M523x 338 depends on M523x
@@ -465,10 +476,10 @@ config ARNEWSH
465 default y 476 default y
466 depends on (ARN5206 || ARN5307) 477 depends on (ARN5206 || ARN5307)
467 478
468config MOTOROLA 479config FREESCALE
469 bool 480 bool
470 default y 481 default y
471 depends on (M5206eC3 || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3) 482 depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
472 483
473config HW_FEITH 484config HW_FEITH
474 bool 485 bool
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index b8fdf191b8f6..b6b5c14e55fd 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -14,6 +14,7 @@ platform-$(CONFIG_M68VZ328) := 68VZ328
14platform-$(CONFIG_M68360) := 68360 14platform-$(CONFIG_M68360) := 68360
15platform-$(CONFIG_M5206) := 5206 15platform-$(CONFIG_M5206) := 5206
16platform-$(CONFIG_M5206e) := 5206e 16platform-$(CONFIG_M5206e) := 5206e
17platform-$(CONFIG_M520x) := 520x
17platform-$(CONFIG_M523x) := 523x 18platform-$(CONFIG_M523x) := 523x
18platform-$(CONFIG_M5249) := 5249 19platform-$(CONFIG_M5249) := 5249
19platform-$(CONFIG_M527x) := 527x 20platform-$(CONFIG_M527x) := 527x
@@ -29,7 +30,7 @@ board-$(CONFIG_UCDIMM) := ucdimm
29board-$(CONFIG_UCQUICC) := uCquicc 30board-$(CONFIG_UCQUICC) := uCquicc
30board-$(CONFIG_DRAGEN2) := de2 31board-$(CONFIG_DRAGEN2) := de2
31board-$(CONFIG_ARNEWSH) := ARNEWSH 32board-$(CONFIG_ARNEWSH) := ARNEWSH
32board-$(CONFIG_MOTOROLA) := MOTOROLA 33board-$(CONFIG_FREESCALE) := FREESCALE
33board-$(CONFIG_M5235EVB) := M5235EVB 34board-$(CONFIG_M5235EVB) := M5235EVB
34board-$(CONFIG_M5271EVB) := M5271EVB 35board-$(CONFIG_M5271EVB) := M5271EVB
35board-$(CONFIG_M5275EVB) := M5275EVB 36board-$(CONFIG_M5275EVB) := M5275EVB
@@ -41,6 +42,7 @@ board-$(CONFIG_SECUREEDGEMP3) := MP3
41board-$(CONFIG_CLEOPATRA) := CLEOPATRA 42board-$(CONFIG_CLEOPATRA) := CLEOPATRA
42board-$(CONFIG_senTec) := senTec 43board-$(CONFIG_senTec) := senTec
43board-$(CONFIG_SNEHA) := SNEHA 44board-$(CONFIG_SNEHA) := SNEHA
45board-$(CONFIG_M5208EVB) := M5208EVB
44board-$(CONFIG_MOD5272) := MOD5272 46board-$(CONFIG_MOD5272) := MOD5272
45BOARD := $(board-y) 47BOARD := $(board-y)
46 48
@@ -56,6 +58,7 @@ MODEL := $(model-y)
56# 58#
57cpuclass-$(CONFIG_M5206) := 5307 59cpuclass-$(CONFIG_M5206) := 5307
58cpuclass-$(CONFIG_M5206e) := 5307 60cpuclass-$(CONFIG_M5206e) := 5307
61cpuclass-$(CONFIG_M520x) := 5307
59cpuclass-$(CONFIG_M523x) := 5307 62cpuclass-$(CONFIG_M523x) := 5307
60cpuclass-$(CONFIG_M5249) := 5307 63cpuclass-$(CONFIG_M5249) := 5307
61cpuclass-$(CONFIG_M527x) := 5307 64cpuclass-$(CONFIG_M527x) := 5307
@@ -80,6 +83,7 @@ export PLATFORM BOARD MODEL CPUCLASS
80# 83#
81cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200 84cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200
82cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200 85cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200
86cflags-$(CONFIG_M520x) := -m5307 -Wa,-S -Wa,-m5307
83cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307 87cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307
84cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200 88cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200
85cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307 89cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307
@@ -95,7 +99,6 @@ cflags-$(CONFIG_M68360) := -m68332
95AFLAGS += $(cflags-y) 99AFLAGS += $(cflags-y)
96 100
97CFLAGS += $(cflags-y) 101CFLAGS += $(cflags-y)
98CFLAGS += -fno-builtin
99CFLAGS += -O1 -g 102CFLAGS += -O1 -g
100CFLAGS += -D__linux__ 103CFLAGS += -D__linux__
101CFLAGS += -DUTS_SYSNAME=\"uClinux\" 104CFLAGS += -DUTS_SYSNAME=\"uClinux\"
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index cd3ffe12653e..b988c7bdc6e4 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -15,6 +15,7 @@
15#include <linux/hardirq.h> 15#include <linux/hardirq.h>
16#include <asm/bootinfo.h> 16#include <asm/bootinfo.h>
17#include <asm/irq.h> 17#include <asm/irq.h>
18#include <asm/irqnode.h>
18#include <asm/thread_info.h> 19#include <asm/thread_info.h>
19 20
20#define DEFINE(sym, val) \ 21#define DEFINE(sym, val) \
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 621d7b91ccfe..262ab8c72e5f 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -101,43 +101,10 @@ void ptrace_disable(struct task_struct *child)
101 put_reg(child, PT_SR, tmp); 101 put_reg(child, PT_SR, tmp);
102} 102}
103 103
104asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 104long arch_ptrace(truct task_struct *child, long request, long addr, long data)
105{ 105{
106 struct task_struct *child;
107 int ret; 106 int ret;
108 107
109 lock_kernel();
110 ret = -EPERM;
111 if (request == PTRACE_TRACEME) {
112 /* are we already being traced? */
113 if (current->ptrace & PT_PTRACED)
114 goto out;
115 /* set the ptrace bit in the process flags. */
116 current->ptrace |= PT_PTRACED;
117 ret = 0;
118 goto out;
119 }
120 ret = -ESRCH;
121 read_lock(&tasklist_lock);
122 child = find_task_by_pid(pid);
123 if (child)
124 get_task_struct(child);
125 read_unlock(&tasklist_lock);
126 if (!child)
127 goto out;
128
129 ret = -EPERM;
130 if (pid == 1) /* you may not mess with init */
131 goto out_tsk;
132
133 if (request == PTRACE_ATTACH) {
134 ret = ptrace_attach(child);
135 goto out_tsk;
136 }
137 ret = ptrace_check_attach(child, request == PTRACE_KILL);
138 if (ret < 0)
139 goto out_tsk;
140
141 switch (request) { 108 switch (request) {
142 /* when I and D space are separate, these will need to be fixed. */ 109 /* when I and D space are separate, these will need to be fixed. */
143 case PTRACE_PEEKTEXT: /* read word at location addr. */ 110 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -357,10 +324,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
357 ret = -EIO; 324 ret = -EIO;
358 break; 325 break;
359 } 326 }
360out_tsk:
361 put_task_struct(child);
362out:
363 unlock_kernel();
364 return ret; 327 return ret;
365} 328}
366 329
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index a220345e9746..abb80fa2b940 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -107,6 +107,9 @@ void (*mach_power_off)( void ) = NULL;
107#if defined(CONFIG_M5206e) 107#if defined(CONFIG_M5206e)
108 #define CPU "COLDFIRE(m5206e)" 108 #define CPU "COLDFIRE(m5206e)"
109#endif 109#endif
110#if defined(CONFIG_M520x)
111 #define CPU "COLDFIRE(m520x)"
112#endif
110#if defined(CONFIG_M523x) 113#if defined(CONFIG_M523x)
111 #define CPU "COLDFIRE(m523x)" 114 #define CPU "COLDFIRE(m523x)"
112#endif 115#endif
@@ -132,7 +135,7 @@ void (*mach_power_off)( void ) = NULL;
132 #define CPU "COLDFIRE(m5407)" 135 #define CPU "COLDFIRE(m5407)"
133#endif 136#endif
134#ifndef CPU 137#ifndef CPU
135 #define CPU "UNKOWN" 138 #define CPU "UNKNOWN"
136#endif 139#endif
137 140
138/* (es) */ 141/* (es) */
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 47f06787190d..0eab92ca4b97 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -125,6 +125,14 @@
125#endif 125#endif
126 126
127/* 127/*
128 * The Freescale 5208EVB board has 32MB of RAM.
129 */
130#if defined(CONFIG_M5208EVB)
131#define RAM_START 0x40020000
132#define RAM_LENGTH 0x01e00000
133#endif
134
135/*
128 * The senTec COBRA5272 board has nearly the same memory layout as 136 * The senTec COBRA5272 board has nearly the same memory layout as
129 * the M5272C3. We assume 16MiB ram. 137 * the M5272C3. We assume 16MiB ram.
130 */ 138 */
@@ -275,6 +283,7 @@ SECTIONS {
275 *(__ksymtab_strings) 283 *(__ksymtab_strings)
276 284
277 /* Built-in module parameters */ 285 /* Built-in module parameters */
286 . = ALIGN(4) ;
278 __start___param = .; 287 __start___param = .;
279 *(__param) 288 *(__param)
280 __stop___param = .; 289 __stop___param = .;
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
new file mode 100644
index 000000000000..e861b05106bc
--- /dev/null
+++ b/arch/m68knommu/platform/520x/Makefile
@@ -0,0 +1,19 @@
1#
2# Makefile for the M5208 specific file.
3#
4
5#
6# If you want to play with the HW breakpoints then you will
7# need to add define this, which will give you a stack backtrace
8# on the console port whenever a DBG interrupt occurs. You have to
9# set up you HW breakpoints to trigger a DBG interrupt:
10#
11# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
12# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
13#
14
15ifdef CONFIG_FULLDEBUG
16AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
17endif
18
19obj-y := config.o
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
new file mode 100644
index 000000000000..71dea2e0f452
--- /dev/null
+++ b/arch/m68knommu/platform/520x/config.c
@@ -0,0 +1,65 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/520x/config.c
5 *
6 * Copyright (C) 2005, Freescale (www.freescale.com)
7 * Copyright (C) 2005, Intec Automation (mike@steroidmicros.com)
8 * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
10 */
11
12/***************************************************************************/
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/param.h>
17#include <asm/machdep.h>
18#include <asm/dma.h>
19
20/***************************************************************************/
21
22/*
23 * DMA channel base address table.
24 */
25unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
26unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
27
28/***************************************************************************/
29
30void coldfire_pit_tick(void);
31void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
32unsigned long coldfire_pit_offset(void);
33void coldfire_trap_init(void);
34void coldfire_reset(void);
35
36/***************************************************************************/
37
38/*
39 * Program the vector to be an auto-vectored.
40 */
41
42void mcf_autovector(unsigned int vec)
43{
44 /* Everything is auto-vectored on the 520x devices */
45}
46
47/***************************************************************************/
48
49void config_BSP(char *commandp, int size)
50{
51#ifdef CONFIG_BOOTPARAM
52 strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
53 commandp[size-1] = 0;
54#else
55 memset(commandp, 0, size);
56#endif
57
58 mach_sched_init = coldfire_pit_init;
59 mach_tick = coldfire_pit_tick;
60 mach_gettimeoffset = coldfire_pit_offset;
61 mach_trap_init = coldfire_trap_init;
62 mach_reset = coldfire_reset;
63}
64
65/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 6fe5a2b8fb08..8d1619dc1ea6 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -19,6 +19,7 @@ endif
19obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o 19obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
20obj-$(CONFIG_M5206) += timers.o 20obj-$(CONFIG_M5206) += timers.o
21obj-$(CONFIG_M5206e) += timers.o 21obj-$(CONFIG_M5206e) += timers.o
22obj-$(CONFIG_M520x) += pit.o
22obj-$(CONFIG_M523x) += pit.o 23obj-$(CONFIG_M523x) += pit.o
23obj-$(CONFIG_M5249) += timers.o 24obj-$(CONFIG_M5249) += timers.o
24obj-$(CONFIG_M527x) += pit.o 25obj-$(CONFIG_M527x) += pit.o
diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
index 7f4ba837901f..c30c462b99b1 100644
--- a/arch/m68knommu/platform/5307/head.S
+++ b/arch/m68knommu/platform/5307/head.S
@@ -113,6 +113,9 @@
113#define MEM_BASE 0x02000000 113#define MEM_BASE 0x02000000
114#define VBR_BASE 0x20000000 /* vectors in SRAM */ 114#define VBR_BASE 0x20000000 /* vectors in SRAM */
115#endif 115#endif
116#if defined(CONFIG_M5208EVB)
117#define MEM_BASE 0x40000000
118#endif
116 119
117#ifndef MEM_BASE 120#ifndef MEM_BASE
118#define MEM_BASE 0x00000000 /* memory base at address 0 */ 121#define MEM_BASE 0x00000000 /* memory base at address 0 */
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
index 0117754d44f3..a134fb2f0566 100644
--- a/arch/m68knommu/platform/5307/ints.c
+++ b/arch/m68knommu/platform/5307/ints.c
@@ -26,6 +26,7 @@
26 26
27#include <asm/system.h> 27#include <asm/system.h>
28#include <asm/irq.h> 28#include <asm/irq.h>
29#include <asm/irqnode.h>
29#include <asm/traps.h> 30#include <asm/traps.h>
30#include <asm/page.h> 31#include <asm/page.h>
31#include <asm/machdep.h> 32#include <asm/machdep.h>
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
index a9b2c2e7e280..323f2677e49d 100644
--- a/arch/m68knommu/platform/5307/pit.c
+++ b/arch/m68knommu/platform/5307/pit.c
@@ -3,7 +3,7 @@
3/* 3/*
4 * pit.c -- Motorola ColdFire PIT timer. Currently this type of 4 * pit.c -- Motorola ColdFire PIT timer. Currently this type of
5 * hardware timer only exists in the Motorola ColdFire 5 * hardware timer only exists in the Motorola ColdFire
6 * 5270/5271 and 5282 CPUs. 6 * 5270/5271, 5282 and other CPUs.
7 * 7 *
8 * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) 8 * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) 9 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
@@ -47,10 +47,10 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
47 47
48 icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 + 48 icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
49 MCFINTC_ICR0 + MCFINT_PIT1); 49 MCFINTC_ICR0 + MCFINT_PIT1);
50 *icrp = 0x2b; /* PIT1 with level 5, priority 3 */ 50 *icrp = ICR_INTRCONF;
51 51
52 imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); 52 imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
53 *imrp &= ~(1 << (MCFINT_PIT1 - 32)); 53 *imrp &= ~MCFPIT_IMR_IBIT;
54 54
55 /* Set up PIT timer 1 as poll clock */ 55 /* Set up PIT timer 1 as poll clock */
56 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); 56 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
@@ -70,7 +70,7 @@ unsigned long coldfire_pit_offset(void)
70 unsigned long pmr, pcntr, offset; 70 unsigned long pmr, pcntr, offset;
71 71
72 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); 72 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
73 ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH); 73 ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
74 74
75 pmr = *(&tp->pmr); 75 pmr = *(&tp->pmr);
76 pcntr = *(&tp->pcntr); 76 pcntr = *(&tp->pcntr);
@@ -80,7 +80,7 @@ unsigned long coldfire_pit_offset(void)
80 * timer interupt is pending, then add on a ticks worth of time. 80 * timer interupt is pending, then add on a ticks worth of time.
81 */ 81 */
82 offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr; 82 offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
83 if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (MCFINT_PIT1 - 32)))) 83 if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
84 offset += 1000000 / HZ; 84 offset += 1000000 / HZ;
85 return offset; 85 return offset;
86} 86}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0097a0d53b3b..e380a8322a94 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -958,7 +958,7 @@ config SOC_PNX8550
958 bool 958 bool
959 select DMA_NONCOHERENT 959 select DMA_NONCOHERENT
960 select HW_HAS_PCI 960 select HW_HAS_PCI
961 select SYS_HAS_CPU_R4X00 961 select SYS_HAS_CPU_MIPS32_R1
962 select SYS_SUPPORTS_32BIT_KERNEL 962 select SYS_SUPPORTS_32BIT_KERNEL
963 963
964config SWAP_IO_SPACE 964config SWAP_IO_SPACE
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
new file mode 100644
index 000000000000..ba63401c6e10
--- /dev/null
+++ b/arch/mips/boot/.gitignore
@@ -0,0 +1,4 @@
1mkboot
2elf2ecoff
3zImage
4zImage.tmp
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 95f84d711912..555837e4c06f 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -129,7 +129,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
129# 129#
130# CPU selection 130# CPU selection
131# 131#
132# CONFIG_CPU_MIPS32_R1 is not set 132CONFIG_CPU_MIPS32_R1=y
133# CONFIG_CPU_MIPS32_R2 is not set 133# CONFIG_CPU_MIPS32_R2 is not set
134# CONFIG_CPU_MIPS64_R1 is not set 134# CONFIG_CPU_MIPS64_R1 is not set
135# CONFIG_CPU_MIPS64_R2 is not set 135# CONFIG_CPU_MIPS64_R2 is not set
@@ -137,7 +137,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
137# CONFIG_CPU_TX39XX is not set 137# CONFIG_CPU_TX39XX is not set
138# CONFIG_CPU_VR41XX is not set 138# CONFIG_CPU_VR41XX is not set
139# CONFIG_CPU_R4300 is not set 139# CONFIG_CPU_R4300 is not set
140CONFIG_CPU_R4X00=y 140# CONFIG_CPU_R4X00 is not set
141# CONFIG_CPU_TX49XX is not set 141# CONFIG_CPU_TX49XX is not set
142# CONFIG_CPU_R5000 is not set 142# CONFIG_CPU_R5000 is not set
143# CONFIG_CPU_R5432 is not set 143# CONFIG_CPU_R5432 is not set
@@ -148,10 +148,11 @@ CONFIG_CPU_R4X00=y
148# CONFIG_CPU_RM7000 is not set 148# CONFIG_CPU_RM7000 is not set
149# CONFIG_CPU_RM9000 is not set 149# CONFIG_CPU_RM9000 is not set
150# CONFIG_CPU_SB1 is not set 150# CONFIG_CPU_SB1 is not set
151CONFIG_SYS_HAS_CPU_R4X00=y 151CONFIG_SYS_HAS_CPU_MIPS32_R1=y
152CONFIG_CPU_MIPS32=y
153CONFIG_CPU_MIPSR1=y
152CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y 154CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
153CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y 155CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
154CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
155 156
156# 157#
157# Kernel type 158# Kernel type
@@ -162,11 +163,11 @@ CONFIG_PAGE_SIZE_4KB=y
162# CONFIG_PAGE_SIZE_8KB is not set 163# CONFIG_PAGE_SIZE_8KB is not set
163# CONFIG_PAGE_SIZE_16KB is not set 164# CONFIG_PAGE_SIZE_16KB is not set
164# CONFIG_PAGE_SIZE_64KB is not set 165# CONFIG_PAGE_SIZE_64KB is not set
166CONFIG_CPU_HAS_PREFETCH=y
165# CONFIG_MIPS_MT is not set 167# CONFIG_MIPS_MT is not set
166# CONFIG_64BIT_PHYS_ADDR is not set 168# CONFIG_64BIT_PHYS_ADDR is not set
167# CONFIG_CPU_ADVANCED is not set 169# CONFIG_CPU_ADVANCED is not set
168CONFIG_CPU_HAS_LLSC=y 170CONFIG_CPU_HAS_LLSC=y
169CONFIG_CPU_HAS_LLDSCD=y
170CONFIG_CPU_HAS_SYNC=y 171CONFIG_CPU_HAS_SYNC=y
171CONFIG_GENERIC_HARDIRQS=y 172CONFIG_GENERIC_HARDIRQS=y
172CONFIG_GENERIC_IRQ_PROBE=y 173CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index deb24c29ac0a..05e65206a7b4 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -128,7 +128,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
128# 128#
129# CPU selection 129# CPU selection
130# 130#
131# CONFIG_CPU_MIPS32_R1 is not set 131CONFIG_CPU_MIPS32_R1=y
132# CONFIG_CPU_MIPS32_R2 is not set 132# CONFIG_CPU_MIPS32_R2 is not set
133# CONFIG_CPU_MIPS64_R1 is not set 133# CONFIG_CPU_MIPS64_R1 is not set
134# CONFIG_CPU_MIPS64_R2 is not set 134# CONFIG_CPU_MIPS64_R2 is not set
@@ -136,7 +136,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
136# CONFIG_CPU_TX39XX is not set 136# CONFIG_CPU_TX39XX is not set
137# CONFIG_CPU_VR41XX is not set 137# CONFIG_CPU_VR41XX is not set
138# CONFIG_CPU_R4300 is not set 138# CONFIG_CPU_R4300 is not set
139CONFIG_CPU_R4X00=y 139# CONFIG_CPU_R4X00 is not set
140# CONFIG_CPU_TX49XX is not set 140# CONFIG_CPU_TX49XX is not set
141# CONFIG_CPU_R5000 is not set 141# CONFIG_CPU_R5000 is not set
142# CONFIG_CPU_R5432 is not set 142# CONFIG_CPU_R5432 is not set
@@ -147,10 +147,11 @@ CONFIG_CPU_R4X00=y
147# CONFIG_CPU_RM7000 is not set 147# CONFIG_CPU_RM7000 is not set
148# CONFIG_CPU_RM9000 is not set 148# CONFIG_CPU_RM9000 is not set
149# CONFIG_CPU_SB1 is not set 149# CONFIG_CPU_SB1 is not set
150CONFIG_SYS_HAS_CPU_R4X00=y 150CONFIG_SYS_HAS_CPU_MIPS32_R1=y
151CONFIG_CPU_MIPS32=y
152CONFIG_CPU_MIPSR1=y
151CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y 153CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
152CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y 154CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
153CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
154 155
155# 156#
156# Kernel type 157# Kernel type
@@ -161,6 +162,7 @@ CONFIG_PAGE_SIZE_4KB=y
161# CONFIG_PAGE_SIZE_8KB is not set 162# CONFIG_PAGE_SIZE_8KB is not set
162# CONFIG_PAGE_SIZE_16KB is not set 163# CONFIG_PAGE_SIZE_16KB is not set
163# CONFIG_PAGE_SIZE_64KB is not set 164# CONFIG_PAGE_SIZE_64KB is not set
165CONFIG_CPU_HAS_PREFETCH=y
164# CONFIG_MIPS_MT is not set 166# CONFIG_MIPS_MT is not set
165# CONFIG_64BIT_PHYS_ADDR is not set 167# CONFIG_64BIT_PHYS_ADDR is not set
166CONFIG_CPU_ADVANCED=y 168CONFIG_CPU_ADVANCED=y
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
index f5b11508ff2f..995896ac0e39 100644
--- a/arch/mips/ddb5xxx/common/rtc_ds1386.c
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c
@@ -41,7 +41,9 @@ rtc_ds1386_get_time(void)
41 u8 byte; 41 u8 byte;
42 u8 temp; 42 u8 temp;
43 unsigned int year, month, day, hour, minute, second; 43 unsigned int year, month, day, hour, minute, second;
44 unsigned long flags;
44 45
46 spin_lock_irqsave(&rtc_lock, flags);
45 /* let us freeze external registers */ 47 /* let us freeze external registers */
46 byte = READ_RTC(0xB); 48 byte = READ_RTC(0xB);
47 byte &= 0x3f; 49 byte &= 0x3f;
@@ -60,6 +62,7 @@ rtc_ds1386_get_time(void)
60 /* enable time transfer */ 62 /* enable time transfer */
61 byte |= 0x80; 63 byte |= 0x80;
62 WRITE_RTC(0xB, byte); 64 WRITE_RTC(0xB, byte);
65 spin_unlock_irqrestore(&rtc_lock, flags);
63 66
64 /* calc hour */ 67 /* calc hour */
65 if (temp & 0x40) { 68 if (temp & 0x40) {
@@ -81,7 +84,9 @@ rtc_ds1386_set_time(unsigned long t)
81 u8 byte; 84 u8 byte;
82 u8 temp; 85 u8 temp;
83 u8 year, month, day, hour, minute, second; 86 u8 year, month, day, hour, minute, second;
87 unsigned long flags;
84 88
89 spin_lock_irqsave(&rtc_lock, flags);
85 /* let us freeze external registers */ 90 /* let us freeze external registers */
86 byte = READ_RTC(0xB); 91 byte = READ_RTC(0xB);
87 byte &= 0x3f; 92 byte &= 0x3f;
@@ -133,6 +138,7 @@ rtc_ds1386_set_time(unsigned long t)
133 if (second != READ_RTC(0x1)) { 138 if (second != READ_RTC(0x1)) {
134 WRITE_RTC(0x1, second); 139 WRITE_RTC(0x1, second);
135 } 140 }
141 spin_unlock_irqrestore(&rtc_lock, flags);
136 142
137 return 0; 143 return 0;
138} 144}
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index dc7091caa7aa..174822344131 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -37,10 +37,25 @@
37#include <asm/dec/machtype.h> 37#include <asm/dec/machtype.h>
38 38
39 39
40/*
41 * Returns true if a clock update is in progress
42 */
43static inline unsigned char dec_rtc_is_updating(void)
44{
45 unsigned char uip;
46 unsigned long flags;
47
48 spin_lock_irqsave(&rtc_lock, flags);
49 uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
50 spin_unlock_irqrestore(&rtc_lock, flags);
51 return uip;
52}
53
40static unsigned long dec_rtc_get_time(void) 54static unsigned long dec_rtc_get_time(void)
41{ 55{
42 unsigned int year, mon, day, hour, min, sec, real_year; 56 unsigned int year, mon, day, hour, min, sec, real_year;
43 int i; 57 int i;
58 unsigned long flags;
44 59
45 /* The Linux interpretation of the DS1287 clock register contents: 60 /* The Linux interpretation of the DS1287 clock register contents:
46 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the 61 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
@@ -49,11 +64,12 @@ static unsigned long dec_rtc_get_time(void)
49 */ 64 */
50 /* read RTC exactly on falling edge of update flag */ 65 /* read RTC exactly on falling edge of update flag */
51 for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ 66 for (i = 0; i < 1000000; i++) /* may take up to 1 second... */
52 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) 67 if (dec_rtc_is_updating())
53 break; 68 break;
54 for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ 69 for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */
55 if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) 70 if (!dec_rtc_is_updating())
56 break; 71 break;
72 spin_lock_irqsave(&rtc_lock, flags);
57 /* Isn't this overkill? UIP above should guarantee consistency */ 73 /* Isn't this overkill? UIP above should guarantee consistency */
58 do { 74 do {
59 sec = CMOS_READ(RTC_SECONDS); 75 sec = CMOS_READ(RTC_SECONDS);
@@ -77,6 +93,7 @@ static unsigned long dec_rtc_get_time(void)
77 * of unused BBU RAM locations. 93 * of unused BBU RAM locations.
78 */ 94 */
79 real_year = CMOS_READ(RTC_DEC_YEAR); 95 real_year = CMOS_READ(RTC_DEC_YEAR);
96 spin_unlock_irqrestore(&rtc_lock, flags);
80 year += real_year - 72 + 2000; 97 year += real_year - 72 + 2000;
81 98
82 return mktime(year, mon, day, hour, min, sec); 99 return mktime(year, mon, day, hour, min, sec);
@@ -95,6 +112,8 @@ static int dec_rtc_set_mmss(unsigned long nowtime)
95 int real_seconds, real_minutes, cmos_minutes; 112 int real_seconds, real_minutes, cmos_minutes;
96 unsigned char save_control, save_freq_select; 113 unsigned char save_control, save_freq_select;
97 114
115 /* irq are locally disabled here */
116 spin_lock(&rtc_lock);
98 /* tell the clock it's being set */ 117 /* tell the clock it's being set */
99 save_control = CMOS_READ(RTC_CONTROL); 118 save_control = CMOS_READ(RTC_CONTROL);
100 CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL); 119 CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);
@@ -141,6 +160,7 @@ static int dec_rtc_set_mmss(unsigned long nowtime)
141 */ 160 */
142 CMOS_WRITE(save_control, RTC_CONTROL); 161 CMOS_WRITE(save_control, RTC_CONTROL);
143 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 162 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
163 spin_unlock(&rtc_lock);
144 164
145 return retval; 165 return retval;
146} 166}
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c
index 1ae4318e1358..8b407d7dc460 100644
--- a/arch/mips/jmr3927/common/rtc_ds1742.c
+++ b/arch/mips/jmr3927/common/rtc_ds1742.c
@@ -57,7 +57,9 @@ rtc_ds1742_get_time(void)
57{ 57{
58 unsigned int year, month, day, hour, minute, second; 58 unsigned int year, month, day, hour, minute, second;
59 unsigned int century; 59 unsigned int century;
60 unsigned long flags;
60 61
62 spin_lock_irqsave(&rtc_lock, flags);
61 CMOS_WRITE(RTC_READ, RTC_CONTROL); 63 CMOS_WRITE(RTC_READ, RTC_CONTROL);
62 second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); 64 second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
63 minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); 65 minute = BCD2BIN(CMOS_READ(RTC_MINUTES));
@@ -67,6 +69,7 @@ rtc_ds1742_get_time(void)
67 year = BCD2BIN(CMOS_READ(RTC_YEAR)); 69 year = BCD2BIN(CMOS_READ(RTC_YEAR));
68 century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); 70 century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK);
69 CMOS_WRITE(0, RTC_CONTROL); 71 CMOS_WRITE(0, RTC_CONTROL);
72 spin_unlock_irqrestore(&rtc_lock, flags);
70 73
71 year += century * 100; 74 year += century * 100;
72 75
@@ -81,7 +84,9 @@ rtc_ds1742_set_time(unsigned long t)
81 u8 year, month, day, hour, minute, second; 84 u8 year, month, day, hour, minute, second;
82 u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; 85 u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second;
83 int cmos_century; 86 int cmos_century;
87 unsigned long flags;
84 88
89 spin_lock_irqsave(&rtc_lock, flags);
85 CMOS_WRITE(RTC_READ, RTC_CONTROL); 90 CMOS_WRITE(RTC_READ, RTC_CONTROL);
86 cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); 91 cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
87 cmos_minute = (u8)CMOS_READ(RTC_MINUTES); 92 cmos_minute = (u8)CMOS_READ(RTC_MINUTES);
@@ -139,6 +144,7 @@ rtc_ds1742_set_time(unsigned long t)
139 144
140 /* RTC_CENTURY and RTC_CONTROL share same address... */ 145 /* RTC_CENTURY and RTC_CONTROL share same address... */
141 CMOS_WRITE(cmos_century, RTC_CONTROL); 146 CMOS_WRITE(cmos_century, RTC_CONTROL);
147 spin_unlock_irqrestore(&rtc_lock, flags);
142 148
143 return 0; 149 return 0;
144} 150}
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 908e63684208..dd118c60bcd0 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -502,8 +502,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
502 while(1) { 502 while(1) {
503 long tmp = 0; 503 long tmp = 0;
504 504
505 current->state = TASK_INTERRUPTIBLE; 505 expire = schedule_timeout_interruptible(expire);
506 expire = schedule_timeout(expire);
507 506
508 for (i=0; i<=4; i++) 507 for (i=0; i<=4; i++)
509 tmp |= (current->pending.signal.sig[i] & kset.sig[i]); 508 tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index f1b0f3e1f95b..510da5fda567 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -174,51 +174,10 @@ int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
174 return 0; 174 return 0;
175} 175}
176 176
177asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 177long arch_ptrace(struct task_struct *child, long request, long addr, long data)
178{ 178{
179 struct task_struct *child;
180 int ret; 179 int ret;
181 180
182#if 0
183 printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
184 (int) request, (int) pid, (unsigned long) addr,
185 (unsigned long) data);
186#endif
187 lock_kernel();
188 ret = -EPERM;
189 if (request == PTRACE_TRACEME) {
190 /* are we already being traced? */
191 if (current->ptrace & PT_PTRACED)
192 goto out;
193 if ((ret = security_ptrace(current->parent, current)))
194 goto out;
195 /* set the ptrace bit in the process flags. */
196 current->ptrace |= PT_PTRACED;
197 ret = 0;
198 goto out;
199 }
200 ret = -ESRCH;
201 read_lock(&tasklist_lock);
202 child = find_task_by_pid(pid);
203 if (child)
204 get_task_struct(child);
205 read_unlock(&tasklist_lock);
206 if (!child)
207 goto out;
208
209 ret = -EPERM;
210 if (pid == 1) /* you may not mess with init */
211 goto out_tsk;
212
213 if (request == PTRACE_ATTACH) {
214 ret = ptrace_attach(child);
215 goto out_tsk;
216 }
217
218 ret = ptrace_check_attach(child, request == PTRACE_KILL);
219 if (ret < 0)
220 goto out_tsk;
221
222 switch (request) { 181 switch (request) {
223 /* when I and D space are separate, these will need to be fixed. */ 182 /* when I and D space are separate, these will need to be fixed. */
224 case PTRACE_PEEKTEXT: /* read word at location addr. */ 183 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -319,7 +278,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
319 if (!cpu_has_dsp) { 278 if (!cpu_has_dsp) {
320 tmp = 0; 279 tmp = 0;
321 ret = -EIO; 280 ret = -EIO;
322 goto out_tsk; 281 goto out;
323 } 282 }
324 if (child->thread.dsp.used_dsp) { 283 if (child->thread.dsp.used_dsp) {
325 dregs = __get_dsp_regs(child); 284 dregs = __get_dsp_regs(child);
@@ -333,14 +292,14 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
333 if (!cpu_has_dsp) { 292 if (!cpu_has_dsp) {
334 tmp = 0; 293 tmp = 0;
335 ret = -EIO; 294 ret = -EIO;
336 goto out_tsk; 295 goto out;
337 } 296 }
338 tmp = child->thread.dsp.dspcontrol; 297 tmp = child->thread.dsp.dspcontrol;
339 break; 298 break;
340 default: 299 default:
341 tmp = 0; 300 tmp = 0;
342 ret = -EIO; 301 ret = -EIO;
343 goto out_tsk; 302 goto out;
344 } 303 }
345 ret = put_user(tmp, (unsigned long __user *) data); 304 ret = put_user(tmp, (unsigned long __user *) data);
346 break; 305 break;
@@ -495,11 +454,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
495 ret = ptrace_request(child, request, addr, data); 454 ret = ptrace_request(child, request, addr, data);
496 break; 455 break;
497 } 456 }
498 457 out:
499out_tsk:
500 put_task_struct(child);
501out:
502 unlock_kernel();
503 return ret; 458 return ret;
504} 459}
505 460
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 8c81f3cb4e2d..1d855112bac2 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -20,42 +20,42 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <asm/uaccess.h>
24#include <linux/slab.h>
25#include <linux/list.h>
26#include <linux/vmalloc.h>
27#include <linux/elf.h>
28#include <linux/seq_file.h>
29#include <linux/syscalls.h>
30#include <linux/moduleloader.h>
31#include <linux/interrupt.h>
32#include <linux/poll.h> 23#include <linux/poll.h>
33#include <linux/sched.h> 24#include <linux/sched.h>
34#include <linux/wait.h> 25#include <linux/wait.h>
35#include <asm/mipsmtregs.h> 26#include <asm/mipsmtregs.h>
36#include <asm/cacheflush.h> 27#include <asm/bitops.h>
37#include <asm/atomic.h>
38#include <asm/cpu.h> 28#include <asm/cpu.h>
39#include <asm/processor.h> 29#include <asm/processor.h>
40#include <asm/system.h>
41#include <asm/rtlx.h> 30#include <asm/rtlx.h>
31#include <asm/uaccess.h>
42 32
43#define RTLX_MAJOR 64
44#define RTLX_TARG_VPE 1 33#define RTLX_TARG_VPE 1
45 34
46struct rtlx_info *rtlx; 35static struct rtlx_info *rtlx;
47static int major; 36static int major;
48static char module_name[] = "rtlx"; 37static char module_name[] = "rtlx";
49static inline int spacefree(int read, int write, int size); 38static struct irqaction irq;
39static int irq_num;
40
41static inline int spacefree(int read, int write, int size)
42{
43 if (read == write) {
44 /*
45 * never fill the buffer completely, so indexes are always
46 * equal if empty and only empty, or !equal if data available
47 */
48 return size - 1;
49 }
50
51 return ((read + size - write) % size) - 1;
52}
50 53
51static struct chan_waitqueues { 54static struct chan_waitqueues {
52 wait_queue_head_t rt_queue; 55 wait_queue_head_t rt_queue;
53 wait_queue_head_t lx_queue; 56 wait_queue_head_t lx_queue;
54} channel_wqs[RTLX_CHANNELS]; 57} channel_wqs[RTLX_CHANNELS];
55 58
56static struct irqaction irq;
57static int irq_num;
58
59extern void *vpe_get_shared(int index); 59extern void *vpe_get_shared(int index);
60 60
61static void rtlx_dispatch(struct pt_regs *regs) 61static void rtlx_dispatch(struct pt_regs *regs)
@@ -63,9 +63,8 @@ static void rtlx_dispatch(struct pt_regs *regs)
63 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); 63 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
64} 64}
65 65
66irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) 66static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
67{ 67{
68 irqreturn_t r = IRQ_HANDLED;
69 int i; 68 int i;
70 69
71 for (i = 0; i < RTLX_CHANNELS; i++) { 70 for (i = 0; i < RTLX_CHANNELS; i++) {
@@ -75,30 +74,7 @@ irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
75 wake_up_interruptible(&channel_wqs[i].lx_queue); 74 wake_up_interruptible(&channel_wqs[i].lx_queue);
76 } 75 }
77 76
78 return r; 77 return IRQ_HANDLED;
79}
80
81void dump_rtlx(void)
82{
83 int i;
84
85 printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
86
87 for (i = 0; i < RTLX_CHANNELS; i++) {
88 struct rtlx_channel *chan = &rtlx->channel[i];
89
90 printk(" rt_state %d lx_state %d buffer_size %d\n",
91 chan->rt_state, chan->lx_state, chan->buffer_size);
92
93 printk(" rt_read %d rt_write %d\n",
94 chan->rt_read, chan->rt_write);
95
96 printk(" lx_read %d lx_write %d\n",
97 chan->lx_read, chan->lx_write);
98
99 printk(" rt_buffer <%s>\n", chan->rt_buffer);
100 printk(" lx_buffer <%s>\n", chan->lx_buffer);
101 }
102} 78}
103 79
104/* call when we have the address of the shared structure from the SP side. */ 80/* call when we have the address of the shared structure from the SP side. */
@@ -108,7 +84,7 @@ static int rtlx_init(struct rtlx_info *rtlxi)
108 84
109 if (rtlxi->id != RTLX_ID) { 85 if (rtlxi->id != RTLX_ID) {
110 printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi); 86 printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi);
111 return (-ENOEXEC); 87 return -ENOEXEC;
112 } 88 }
113 89
114 /* initialise the wait queues */ 90 /* initialise the wait queues */
@@ -120,9 +96,8 @@ static int rtlx_init(struct rtlx_info *rtlxi)
120 /* set up for interrupt handling */ 96 /* set up for interrupt handling */
121 memset(&irq, 0, sizeof(struct irqaction)); 97 memset(&irq, 0, sizeof(struct irqaction));
122 98
123 if (cpu_has_vint) { 99 if (cpu_has_vint)
124 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); 100 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
125 }
126 101
127 irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; 102 irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;
128 irq.handler = rtlx_interrupt; 103 irq.handler = rtlx_interrupt;
@@ -132,7 +107,8 @@ static int rtlx_init(struct rtlx_info *rtlxi)
132 setup_irq(irq_num, &irq); 107 setup_irq(irq_num, &irq);
133 108
134 rtlx = rtlxi; 109 rtlx = rtlxi;
135 return (0); 110
111 return 0;
136} 112}
137 113
138/* only allow one open process at a time to open each channel */ 114/* only allow one open process at a time to open each channel */
@@ -147,36 +123,36 @@ static int rtlx_open(struct inode *inode, struct file *filp)
147 if (rtlx == NULL) { 123 if (rtlx == NULL) {
148 struct rtlx_info **p; 124 struct rtlx_info **p;
149 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { 125 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
150 printk(" vpe_get_shared is NULL. Has an SP program been loaded?\n"); 126 printk(KERN_ERR "vpe_get_shared is NULL. "
151 return (-EFAULT); 127 "Has an SP program been loaded?\n");
128 return -EFAULT;
152 } 129 }
153 130
154 if (*p == NULL) { 131 if (*p == NULL) {
155 printk(" vpe_shared %p %p\n", p, *p); 132 printk(KERN_ERR "vpe_shared %p %p\n", p, *p);
156 return (-EFAULT); 133 return -EFAULT;
157 } 134 }
158 135
159 if ((ret = rtlx_init(*p)) < 0) 136 if ((ret = rtlx_init(*p)) < 0)
160 return (ret); 137 return ret;
161 } 138 }
162 139
163 chan = &rtlx->channel[minor]; 140 chan = &rtlx->channel[minor];
164 141
165 /* already open? */ 142 if (test_and_set_bit(RTLX_STATE_OPENED, &chan->lx_state))
166 if (chan->lx_state == RTLX_STATE_OPENED) 143 return -EBUSY;
167 return (-EBUSY);
168 144
169 chan->lx_state = RTLX_STATE_OPENED; 145 return 0;
170 return (0);
171} 146}
172 147
173static int rtlx_release(struct inode *inode, struct file *filp) 148static int rtlx_release(struct inode *inode, struct file *filp)
174{ 149{
175 int minor; 150 int minor = MINOR(inode->i_rdev);
176 151
177 minor = MINOR(inode->i_rdev); 152 clear_bit(RTLX_STATE_OPENED, &rtlx->channel[minor].lx_state);
178 rtlx->channel[minor].lx_state = RTLX_STATE_UNUSED; 153 smp_mb__after_clear_bit();
179 return (0); 154
155 return 0;
180} 156}
181 157
182static unsigned int rtlx_poll(struct file *file, poll_table * wait) 158static unsigned int rtlx_poll(struct file *file, poll_table * wait)
@@ -199,12 +175,13 @@ static unsigned int rtlx_poll(struct file *file, poll_table * wait)
199 if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size)) 175 if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size))
200 mask |= POLLOUT | POLLWRNORM; 176 mask |= POLLOUT | POLLWRNORM;
201 177
202 return (mask); 178 return mask;
203} 179}
204 180
205static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count, 181static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
206 loff_t * ppos) 182 loff_t * ppos)
207{ 183{
184 unsigned long failed;
208 size_t fl = 0L; 185 size_t fl = 0L;
209 int minor; 186 int minor;
210 struct rtlx_channel *lx; 187 struct rtlx_channel *lx;
@@ -216,7 +193,7 @@ static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
216 /* data available? */ 193 /* data available? */
217 if (lx->lx_write == lx->lx_read) { 194 if (lx->lx_write == lx->lx_read) {
218 if (file->f_flags & O_NONBLOCK) 195 if (file->f_flags & O_NONBLOCK)
219 return (0); // -EAGAIN makes cat whinge 196 return 0; /* -EAGAIN makes cat whinge */
220 197
221 /* go to sleep */ 198 /* go to sleep */
222 add_wait_queue(&channel_wqs[minor].lx_queue, &wait); 199 add_wait_queue(&channel_wqs[minor].lx_queue, &wait);
@@ -232,39 +209,39 @@ static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
232 } 209 }
233 210
234 /* find out how much in total */ 211 /* find out how much in total */
235 count = min( count, 212 count = min(count,
236 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size); 213 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size);
237 214
238 /* then how much from the read pointer onwards */ 215 /* then how much from the read pointer onwards */
239 fl = min( count, (size_t)lx->buffer_size - lx->lx_read); 216 fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
240 217
241 copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl); 218 failed = copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl);
219 if (failed) {
220 count = fl - failed;
221 goto out;
222 }
242 223
243 /* and if there is anything left at the beginning of the buffer */ 224 /* and if there is anything left at the beginning of the buffer */
244 if ( count - fl ) 225 if (count - fl) {
245 copy_to_user (buffer + fl, lx->lx_buffer, count - fl); 226 failed = copy_to_user (buffer + fl, lx->lx_buffer, count - fl);
227 if (failed) {
228 count -= failed;
229 goto out;
230 }
231 }
246 232
233out:
247 /* update the index */ 234 /* update the index */
248 lx->lx_read += count; 235 lx->lx_read += count;
249 lx->lx_read %= lx->buffer_size; 236 lx->lx_read %= lx->buffer_size;
250 237
251 return (count); 238 return count;
252}
253
254static inline int spacefree(int read, int write, int size)
255{
256 if (read == write) {
257 /* never fill the buffer completely, so indexes are always equal if empty
258 and only empty, or !equal if data available */
259 return (size - 1);
260 }
261
262 return ((read + size - write) % size) - 1;
263} 239}
264 240
265static ssize_t rtlx_write(struct file *file, const char __user * buffer, 241static ssize_t rtlx_write(struct file *file, const char __user * buffer,
266 size_t count, loff_t * ppos) 242 size_t count, loff_t * ppos)
267{ 243{
244 unsigned long failed;
268 int minor; 245 int minor;
269 struct rtlx_channel *rt; 246 struct rtlx_channel *rt;
270 size_t fl; 247 size_t fl;
@@ -277,7 +254,7 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer,
277 if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) { 254 if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) {
278 255
279 if (file->f_flags & O_NONBLOCK) 256 if (file->f_flags & O_NONBLOCK)
280 return (-EAGAIN); 257 return -EAGAIN;
281 258
282 add_wait_queue(&channel_wqs[minor].rt_queue, &wait); 259 add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
283 set_current_state(TASK_INTERRUPTIBLE); 260 set_current_state(TASK_INTERRUPTIBLE);
@@ -290,52 +267,64 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer,
290 } 267 }
291 268
292 /* total number of bytes to copy */ 269 /* total number of bytes to copy */
293 count = min( count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) ); 270 count = min(count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) );
294 271
295 /* first bit from write pointer to the end of the buffer, or count */ 272 /* first bit from write pointer to the end of the buffer, or count */
296 fl = min(count, (size_t) rt->buffer_size - rt->rt_write); 273 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
297 274
298 copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl); 275 failed = copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl);
276 if (failed) {
277 count = fl - failed;
278 goto out;
279 }
299 280
300 /* if there's any left copy to the beginning of the buffer */ 281 /* if there's any left copy to the beginning of the buffer */
301 if( count - fl ) 282 if (count - fl) {
302 copy_from_user(rt->rt_buffer, buffer + fl, count - fl); 283 failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
284 if (failed) {
285 count -= failed;
286 goto out;
287 }
288 }
303 289
290out:
304 rt->rt_write += count; 291 rt->rt_write += count;
305 rt->rt_write %= rt->buffer_size; 292 rt->rt_write %= rt->buffer_size;
306 293
307 return(count); 294 return count;
308} 295}
309 296
310static struct file_operations rtlx_fops = { 297static struct file_operations rtlx_fops = {
311 .owner = THIS_MODULE, 298 .owner = THIS_MODULE,
312 .open = rtlx_open, 299 .open = rtlx_open,
313 .release = rtlx_release, 300 .release = rtlx_release,
314 .write = rtlx_write, 301 .write = rtlx_write,
315 .read = rtlx_read, 302 .read = rtlx_read,
316 .poll = rtlx_poll 303 .poll = rtlx_poll
317}; 304};
318 305
319static int rtlx_module_init(void) 306static char register_chrdev_failed[] __initdata =
307 KERN_ERR "rtlx_module_init: unable to register device\n";
308
309static int __init rtlx_module_init(void)
320{ 310{
321 if ((major = register_chrdev(RTLX_MAJOR, module_name, &rtlx_fops)) < 0) { 311 major = register_chrdev(0, module_name, &rtlx_fops);
322 printk("rtlx_module_init: unable to register device\n"); 312 if (major < 0) {
323 return (-EBUSY); 313 printk(register_chrdev_failed);
314 return major;
324 } 315 }
325 316
326 if (major == 0) 317 return 0;
327 major = RTLX_MAJOR;
328
329 return (0);
330} 318}
331 319
332static void rtlx_module_exit(void) 320static void __exit rtlx_module_exit(void)
333{ 321{
334 unregister_chrdev(major, module_name); 322 unregister_chrdev(major, module_name);
335} 323}
336 324
337module_init(rtlx_module_init); 325module_init(rtlx_module_init);
338module_exit(rtlx_module_exit); 326module_exit(rtlx_module_exit);
327
339MODULE_DESCRIPTION("MIPS RTLX"); 328MODULE_DESCRIPTION("MIPS RTLX");
340MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc"); 329MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc.");
341MODULE_LICENSE("GPL"); 330MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 9202a17db8f7..05e09eedabff 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -384,9 +384,6 @@ give_sigsegv:
384 return 0; 384 return 0;
385} 385}
386 386
387extern void setup_rt_frame_n32(struct k_sigaction * ka,
388 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
389
390static inline int handle_signal(unsigned long sig, siginfo_t *info, 387static inline int handle_signal(unsigned long sig, siginfo_t *info,
391 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 388 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
392{ 389{
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index dbe821303125..e315d3f6aa6e 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -647,8 +647,8 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
647 return (void *)((sp - frame_size) & ALMASK); 647 return (void *)((sp - frame_size) & ALMASK);
648} 648}
649 649
650void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 650int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
651 int signr, sigset_t *set) 651 int signr, sigset_t *set)
652{ 652{
653 struct sigframe *frame; 653 struct sigframe *frame;
654 int err = 0; 654 int err = 0;
@@ -694,13 +694,15 @@ void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
694 current->comm, current->pid, 694 current->comm, current->pid,
695 frame, regs->cp0_epc, frame->sf_code); 695 frame, regs->cp0_epc, frame->sf_code);
696#endif 696#endif
697 return; 697 return 1;
698 698
699give_sigsegv: 699give_sigsegv:
700 force_sigsegv(signr, current); 700 force_sigsegv(signr, current);
701 return 0;
701} 702}
702 703
703void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) 704int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
705 int signr, sigset_t *set, siginfo_t *info)
704{ 706{
705 struct rt_sigframe32 *frame; 707 struct rt_sigframe32 *frame;
706 int err = 0; 708 int err = 0;
@@ -763,10 +765,11 @@ void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr,
763 current->comm, current->pid, 765 current->comm, current->pid,
764 frame, regs->cp0_epc, frame->rs_code); 766 frame, regs->cp0_epc, frame->rs_code);
765#endif 767#endif
766 return; 768 return 1;
767 769
768give_sigsegv: 770give_sigsegv:
769 force_sigsegv(signr, current); 771 force_sigsegv(signr, current);
772 return 0;
770} 773}
771 774
772static inline int handle_signal(unsigned long sig, siginfo_t *info, 775static inline int handle_signal(unsigned long sig, siginfo_t *info,
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 97fefcc9dbe7..06be405be399 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -58,10 +58,6 @@
58 58
59typedef void *vpe_handle; 59typedef void *vpe_handle;
60 60
61// defined here because the kernel module loader doesn't have
62// anything to do with it.
63#define SHN_MIPS_SCOMMON 0xff03
64
65#ifndef ARCH_SHF_SMALL 61#ifndef ARCH_SHF_SMALL
66#define ARCH_SHF_SMALL 0 62#define ARCH_SHF_SMALL 0
67#endif 63#endif
@@ -69,11 +65,8 @@ typedef void *vpe_handle;
69/* If this is set, the section belongs in the init part of the module */ 65/* If this is set, the section belongs in the init part of the module */
70#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) 66#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
71 67
72// temp number,
73#define VPE_MAJOR 63
74
75static char module_name[] = "vpe"; 68static char module_name[] = "vpe";
76static int major = 0; 69static int major;
77 70
78/* grab the likely amount of memory we will need. */ 71/* grab the likely amount of memory we will need. */
79#ifdef CONFIG_MIPS_VPE_LOADER_TOM 72#ifdef CONFIG_MIPS_VPE_LOADER_TOM
@@ -98,22 +91,7 @@ enum tc_state {
98 TC_STATE_DYNAMIC 91 TC_STATE_DYNAMIC
99}; 92};
100 93
101struct vpe; 94struct vpe {
102typedef struct tc {
103 enum tc_state state;
104 int index;
105
106 /* parent VPE */
107 struct vpe *pvpe;
108
109 /* The list of TC's with this VPE */
110 struct list_head tc;
111
112 /* The global list of tc's */
113 struct list_head list;
114} tc_t;
115
116typedef struct vpe {
117 enum vpe_state state; 95 enum vpe_state state;
118 96
119 /* (device) minor associated with this vpe */ 97 /* (device) minor associated with this vpe */
@@ -135,7 +113,21 @@ typedef struct vpe {
135 113
136 /* shared symbol address */ 114 /* shared symbol address */
137 void *shared_ptr; 115 void *shared_ptr;
138} vpe_t; 116};
117
118struct tc {
119 enum tc_state state;
120 int index;
121
122 /* parent VPE */
123 struct vpe *pvpe;
124
125 /* The list of TC's with this VPE */
126 struct list_head tc;
127
128 /* The global list of tc's */
129 struct list_head list;
130};
139 131
140struct vpecontrol_ { 132struct vpecontrol_ {
141 /* Virtual processing elements */ 133 /* Virtual processing elements */
@@ -146,7 +138,7 @@ struct vpecontrol_ {
146} vpecontrol; 138} vpecontrol;
147 139
148static void release_progmem(void *ptr); 140static void release_progmem(void *ptr);
149static void dump_vpe(vpe_t * v); 141static void dump_vpe(struct vpe * v);
150extern void save_gp_address(unsigned int secbase, unsigned int rel); 142extern void save_gp_address(unsigned int secbase, unsigned int rel);
151 143
152/* get the vpe associated with this minor */ 144/* get the vpe associated with this minor */
@@ -197,13 +189,11 @@ struct vpe *alloc_vpe(int minor)
197{ 189{
198 struct vpe *v; 190 struct vpe *v;
199 191
200 if ((v = kmalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { 192 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
201 printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); 193 printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
202 return NULL; 194 return NULL;
203 } 195 }
204 196
205 memset(v, 0, sizeof(struct vpe));
206
207 INIT_LIST_HEAD(&v->tc); 197 INIT_LIST_HEAD(&v->tc);
208 list_add_tail(&v->list, &vpecontrol.vpe_list); 198 list_add_tail(&v->list, &vpecontrol.vpe_list);
209 199
@@ -216,13 +206,11 @@ struct tc *alloc_tc(int index)
216{ 206{
217 struct tc *t; 207 struct tc *t;
218 208
219 if ((t = kmalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { 209 if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
220 printk(KERN_WARNING "VPE: alloc_tc no mem\n"); 210 printk(KERN_WARNING "VPE: alloc_tc no mem\n");
221 return NULL; 211 return NULL;
222 } 212 }
223 213
224 memset(t, 0, sizeof(struct tc));
225
226 INIT_LIST_HEAD(&t->tc); 214 INIT_LIST_HEAD(&t->tc);
227 list_add_tail(&t->list, &vpecontrol.tc_list); 215 list_add_tail(&t->list, &vpecontrol.tc_list);
228 216
@@ -412,16 +400,17 @@ static int apply_r_mips_26(struct module *me, uint32_t *location,
412 return -ENOEXEC; 400 return -ENOEXEC;
413 } 401 }
414 402
415/* Not desperately convinced this is a good check of an overflow condition 403/*
416 anyway. But it gets in the way of handling undefined weak symbols which 404 * Not desperately convinced this is a good check of an overflow condition
417 we want to set to zero. 405 * anyway. But it gets in the way of handling undefined weak symbols which
418 if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 406 * we want to set to zero.
419 printk(KERN_ERR 407 * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
420 "module %s: relocation overflow\n", 408 * printk(KERN_ERR
421 me->name); 409 * "module %s: relocation overflow\n",
422 return -ENOEXEC; 410 * me->name);
423 } 411 * return -ENOEXEC;
424*/ 412 * }
413 */
425 414
426 *location = (*location & ~0x03ffffff) | 415 *location = (*location & ~0x03ffffff) |
427 ((*location + (v >> 2)) & 0x03ffffff); 416 ((*location + (v >> 2)) & 0x03ffffff);
@@ -681,7 +670,7 @@ static void dump_tclist(void)
681} 670}
682 671
683/* We are prepared so configure and start the VPE... */ 672/* We are prepared so configure and start the VPE... */
684int vpe_run(vpe_t * v) 673int vpe_run(struct vpe * v)
685{ 674{
686 unsigned long val; 675 unsigned long val;
687 struct tc *t; 676 struct tc *t;
@@ -772,7 +761,7 @@ int vpe_run(vpe_t * v)
772 return 0; 761 return 0;
773} 762}
774 763
775static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs, 764static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
776 unsigned int symindex, const char *strtab, 765 unsigned int symindex, const char *strtab,
777 struct module *mod) 766 struct module *mod)
778{ 767{
@@ -792,10 +781,12 @@ static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
792 return 0; 781 return 0;
793} 782}
794 783
795/* Allocates a VPE with some program code space(the load address), copies the contents 784/*
796 of the program (p)buffer performing relocatations/etc, free's it when finished. 785 * Allocates a VPE with some program code space(the load address), copies
786 * the contents of the program (p)buffer performing relocatations/etc,
787 * free's it when finished.
797*/ 788*/
798int vpe_elfload(vpe_t * v) 789int vpe_elfload(struct vpe * v)
799{ 790{
800 Elf_Ehdr *hdr; 791 Elf_Ehdr *hdr;
801 Elf_Shdr *sechdrs; 792 Elf_Shdr *sechdrs;
@@ -931,7 +922,7 @@ cleanup:
931 return err; 922 return err;
932} 923}
933 924
934static void dump_vpe(vpe_t * v) 925static void dump_vpe(struct vpe * v)
935{ 926{
936 struct tc *t; 927 struct tc *t;
937 928
@@ -947,7 +938,7 @@ static void dump_vpe(vpe_t * v)
947static int vpe_open(struct inode *inode, struct file *filp) 938static int vpe_open(struct inode *inode, struct file *filp)
948{ 939{
949 int minor; 940 int minor;
950 vpe_t *v; 941 struct vpe *v;
951 942
952 /* assume only 1 device at the mo. */ 943 /* assume only 1 device at the mo. */
953 if ((minor = MINOR(inode->i_rdev)) != 1) { 944 if ((minor = MINOR(inode->i_rdev)) != 1) {
@@ -1001,7 +992,7 @@ static int vpe_open(struct inode *inode, struct file *filp)
1001static int vpe_release(struct inode *inode, struct file *filp) 992static int vpe_release(struct inode *inode, struct file *filp)
1002{ 993{
1003 int minor, ret = 0; 994 int minor, ret = 0;
1004 vpe_t *v; 995 struct vpe *v;
1005 Elf_Ehdr *hdr; 996 Elf_Ehdr *hdr;
1006 997
1007 minor = MINOR(inode->i_rdev); 998 minor = MINOR(inode->i_rdev);
@@ -1035,7 +1026,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
1035{ 1026{
1036 int minor; 1027 int minor;
1037 size_t ret = count; 1028 size_t ret = count;
1038 vpe_t *v; 1029 struct vpe *v;
1039 1030
1040 minor = MINOR(file->f_dentry->d_inode->i_rdev); 1031 minor = MINOR(file->f_dentry->d_inode->i_rdev);
1041 if ((v = get_vpe(minor)) == NULL) 1032 if ((v = get_vpe(minor)) == NULL)
@@ -1180,14 +1171,11 @@ static int __init vpe_module_init(void)
1180 return -ENODEV; 1171 return -ENODEV;
1181 } 1172 }
1182 1173
1183 if ((major = register_chrdev(VPE_MAJOR, module_name, &vpe_fops) < 0)) { 1174 if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) {
1184 printk("VPE loader: unable to register character device\n"); 1175 printk("VPE loader: unable to register character device\n");
1185 return -EBUSY; 1176 return major;
1186 } 1177 }
1187 1178
1188 if (major == 0)
1189 major = VPE_MAJOR;
1190
1191 dmt(); 1179 dmt();
1192 dvpe(); 1180 dvpe();
1193 1181
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
index 9d7812e03dcd..7dced67c55eb 100644
--- a/arch/mips/lasat/ds1603.c
+++ b/arch/mips/lasat/ds1603.c
@@ -8,6 +8,7 @@
8#include <asm/lasat/lasat.h> 8#include <asm/lasat/lasat.h>
9#include <linux/delay.h> 9#include <linux/delay.h>
10#include <asm/lasat/ds1603.h> 10#include <asm/lasat/ds1603.h>
11#include <asm/time.h>
11 12
12#include "ds1603.h" 13#include "ds1603.h"
13 14
@@ -138,19 +139,27 @@ static void rtc_end_op(void)
138unsigned long ds1603_read(void) 139unsigned long ds1603_read(void)
139{ 140{
140 unsigned long word; 141 unsigned long word;
142 unsigned long flags;
143
144 spin_lock_irqsave(&rtc_lock, flags);
141 rtc_init_op(); 145 rtc_init_op();
142 rtc_write_byte(READ_TIME_CMD); 146 rtc_write_byte(READ_TIME_CMD);
143 word = rtc_read_word(); 147 word = rtc_read_word();
144 rtc_end_op(); 148 rtc_end_op();
149 spin_unlock_irqrestore(&rtc_lock, flags);
145 return word; 150 return word;
146} 151}
147 152
148int ds1603_set(unsigned long time) 153int ds1603_set(unsigned long time)
149{ 154{
155 unsigned long flags;
156
157 spin_lock_irqsave(&rtc_lock, flags);
150 rtc_init_op(); 158 rtc_init_op();
151 rtc_write_byte(SET_TIME_CMD); 159 rtc_write_byte(SET_TIME_CMD);
152 rtc_write_word(time); 160 rtc_write_word(time);
153 rtc_end_op(); 161 rtc_end_op();
162 spin_unlock_irqrestore(&rtc_lock, flags);
154 163
155 return 0; 164 return 0;
156} 165}
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index 768bf4406452..bab192ddc185 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -149,7 +149,9 @@ arch_initcall(per_cpu_mappings);
149unsigned long m48t37y_get_time(void) 149unsigned long m48t37y_get_time(void)
150{ 150{
151 unsigned int year, month, day, hour, min, sec; 151 unsigned int year, month, day, hour, min, sec;
152 unsigned long flags;
152 153
154 spin_lock_irqsave(&rtc_lock, flags);
153 /* stop the update */ 155 /* stop the update */
154 rtc_base[0x7ff8] = 0x40; 156 rtc_base[0x7ff8] = 0x40;
155 157
@@ -166,6 +168,7 @@ unsigned long m48t37y_get_time(void)
166 168
167 /* start the update */ 169 /* start the update */
168 rtc_base[0x7ff8] = 0x00; 170 rtc_base[0x7ff8] = 0x00;
171 spin_unlock_irqrestore(&rtc_lock, flags);
169 172
170 return mktime(year, month, day, hour, min, sec); 173 return mktime(year, month, day, hour, min, sec);
171} 174}
@@ -173,11 +176,13 @@ unsigned long m48t37y_get_time(void)
173int m48t37y_set_time(unsigned long sec) 176int m48t37y_set_time(unsigned long sec)
174{ 177{
175 struct rtc_time tm; 178 struct rtc_time tm;
179 unsigned long flags;
176 180
177 /* convert to a more useful format -- note months count from 0 */ 181 /* convert to a more useful format -- note months count from 0 */
178 to_tm(sec, &tm); 182 to_tm(sec, &tm);
179 tm.tm_mon += 1; 183 tm.tm_mon += 1;
180 184
185 spin_lock_irqsave(&rtc_lock, flags);
181 /* enable writing */ 186 /* enable writing */
182 rtc_base[0x7ff8] = 0x80; 187 rtc_base[0x7ff8] = 0x80;
183 188
@@ -201,6 +206,7 @@ int m48t37y_set_time(unsigned long sec)
201 206
202 /* disable writing */ 207 /* disable writing */
203 rtc_base[0x7ff8] = 0x00; 208 rtc_base[0x7ff8] = 0x00;
209 spin_unlock_irqrestore(&rtc_lock, flags);
204 210
205 return 0; 211 return 0;
206} 212}
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index a7803e08f9db..c9b7ff8148ec 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -135,7 +135,9 @@ void setup_wired_tlb_entries(void)
135unsigned long m48t37y_get_time(void) 135unsigned long m48t37y_get_time(void)
136{ 136{
137 unsigned int year, month, day, hour, min, sec; 137 unsigned int year, month, day, hour, min, sec;
138 unsigned long flags;
138 139
140 spin_lock_irqsave(&rtc_lock, flags);
139 /* stop the update */ 141 /* stop the update */
140 rtc_base[0x7ff8] = 0x40; 142 rtc_base[0x7ff8] = 0x40;
141 143
@@ -152,6 +154,7 @@ unsigned long m48t37y_get_time(void)
152 154
153 /* start the update */ 155 /* start the update */
154 rtc_base[0x7ff8] = 0x00; 156 rtc_base[0x7ff8] = 0x00;
157 spin_unlock_irqrestore(&rtc_lock, flags);
155 158
156 return mktime(year, month, day, hour, min, sec); 159 return mktime(year, month, day, hour, min, sec);
157} 160}
@@ -159,11 +162,13 @@ unsigned long m48t37y_get_time(void)
159int m48t37y_set_time(unsigned long sec) 162int m48t37y_set_time(unsigned long sec)
160{ 163{
161 struct rtc_time tm; 164 struct rtc_time tm;
165 unsigned long flags;
162 166
163 /* convert to a more useful format -- note months count from 0 */ 167 /* convert to a more useful format -- note months count from 0 */
164 to_tm(sec, &tm); 168 to_tm(sec, &tm);
165 tm.tm_mon += 1; 169 tm.tm_mon += 1;
166 170
171 spin_lock_irqsave(&rtc_lock, flags);
167 /* enable writing */ 172 /* enable writing */
168 rtc_base[0x7ff8] = 0x80; 173 rtc_base[0x7ff8] = 0x80;
169 174
@@ -187,6 +192,7 @@ int m48t37y_set_time(unsigned long sec)
187 192
188 /* disable writing */ 193 /* disable writing */
189 rtc_base[0x7ff8] = 0x00; 194 rtc_base[0x7ff8] = 0x00;
195 spin_unlock_irqrestore(&rtc_lock, flags);
190 196
191 return 0; 197 return 0;
192} 198}
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index ce70fc96f160..2755c1547473 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -140,7 +140,9 @@ unsigned long m48t37y_get_time(void)
140 unsigned char* rtc_base = (unsigned char*)0xfc800000; 140 unsigned char* rtc_base = (unsigned char*)0xfc800000;
141#endif 141#endif
142 unsigned int year, month, day, hour, min, sec; 142 unsigned int year, month, day, hour, min, sec;
143 unsigned long flags;
143 144
145 spin_lock_irqsave(&rtc_lock, flags);
144 /* stop the update */ 146 /* stop the update */
145 rtc_base[0x7ff8] = 0x40; 147 rtc_base[0x7ff8] = 0x40;
146 148
@@ -157,6 +159,7 @@ unsigned long m48t37y_get_time(void)
157 159
158 /* start the update */ 160 /* start the update */
159 rtc_base[0x7ff8] = 0x00; 161 rtc_base[0x7ff8] = 0x00;
162 spin_unlock_irqrestore(&rtc_lock, flags);
160 163
161 return mktime(year, month, day, hour, min, sec); 164 return mktime(year, month, day, hour, min, sec);
162} 165}
@@ -169,11 +172,13 @@ int m48t37y_set_time(unsigned long sec)
169 unsigned char* rtc_base = (unsigned char*)0xfc800000; 172 unsigned char* rtc_base = (unsigned char*)0xfc800000;
170#endif 173#endif
171 struct rtc_time tm; 174 struct rtc_time tm;
175 unsigned long flags;
172 176
173 /* convert to a more useful format -- note months count from 0 */ 177 /* convert to a more useful format -- note months count from 0 */
174 to_tm(sec, &tm); 178 to_tm(sec, &tm);
175 tm.tm_mon += 1; 179 tm.tm_mon += 1;
176 180
181 spin_lock_irqsave(&rtc_lock, flags);
177 /* enable writing */ 182 /* enable writing */
178 rtc_base[0x7ff8] = 0x80; 183 rtc_base[0x7ff8] = 0x80;
179 184
@@ -197,6 +202,7 @@ int m48t37y_set_time(unsigned long sec)
197 202
198 /* disable writing */ 203 /* disable writing */
199 rtc_base[0x7ff8] = 0x00; 204 rtc_base[0x7ff8] = 0x00;
205 spin_unlock_irqrestore(&rtc_lock, flags);
200 206
201 return 0; 207 return 0;
202} 208}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index bdc2ab55bed6..059755b5ed57 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -73,7 +73,9 @@ void __init bus_error_init(void)
73unsigned long m48t37y_get_time(void) 73unsigned long m48t37y_get_time(void)
74{ 74{
75 unsigned int year, month, day, hour, min, sec; 75 unsigned int year, month, day, hour, min, sec;
76 unsigned long flags;
76 77
78 spin_lock_irqsave(&rtc_lock, flags);
77 /* Stop the update to the time */ 79 /* Stop the update to the time */
78 m48t37_base->control = 0x40; 80 m48t37_base->control = 0x40;
79 81
@@ -88,6 +90,7 @@ unsigned long m48t37y_get_time(void)
88 90
89 /* Start the update to the time again */ 91 /* Start the update to the time again */
90 m48t37_base->control = 0x00; 92 m48t37_base->control = 0x00;
93 spin_unlock_irqrestore(&rtc_lock, flags);
91 94
92 return mktime(year, month, day, hour, min, sec); 95 return mktime(year, month, day, hour, min, sec);
93} 96}
@@ -95,11 +98,13 @@ unsigned long m48t37y_get_time(void)
95int m48t37y_set_time(unsigned long sec) 98int m48t37y_set_time(unsigned long sec)
96{ 99{
97 struct rtc_time tm; 100 struct rtc_time tm;
101 unsigned long flags;
98 102
99 /* convert to a more useful format -- note months count from 0 */ 103 /* convert to a more useful format -- note months count from 0 */
100 to_tm(sec, &tm); 104 to_tm(sec, &tm);
101 tm.tm_mon += 1; 105 tm.tm_mon += 1;
102 106
107 spin_lock_irqsave(&rtc_lock, flags);
103 /* enable writing */ 108 /* enable writing */
104 m48t37_base->control = 0x80; 109 m48t37_base->control = 0x80;
105 110
@@ -123,6 +128,7 @@ int m48t37y_set_time(unsigned long sec)
123 128
124 /* disable writing */ 129 /* disable writing */
125 m48t37_base->control = 0x00; 130 m48t37_base->control = 0x00;
131 spin_unlock_irqrestore(&rtc_lock, flags);
126 132
127 return 0; 133 return 0;
128} 134}
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index df9b5694328a..b7300cc5c5ad 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -35,7 +35,9 @@ static unsigned long indy_rtc_get_time(void)
35{ 35{
36 unsigned int yrs, mon, day, hrs, min, sec; 36 unsigned int yrs, mon, day, hrs, min, sec;
37 unsigned int save_control; 37 unsigned int save_control;
38 unsigned long flags;
38 39
40 spin_lock_irqsave(&rtc_lock, flags);
39 save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; 41 save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
40 hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; 42 hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
41 43
@@ -47,6 +49,7 @@ static unsigned long indy_rtc_get_time(void)
47 yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff); 49 yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff);
48 50
49 hpc3c0->rtcregs[RTC_CMD] = save_control; 51 hpc3c0->rtcregs[RTC_CMD] = save_control;
52 spin_unlock_irqrestore(&rtc_lock, flags);
50 53
51 if (yrs < 45) 54 if (yrs < 45)
52 yrs += 30; 55 yrs += 30;
@@ -60,6 +63,7 @@ static int indy_rtc_set_time(unsigned long tim)
60{ 63{
61 struct rtc_time tm; 64 struct rtc_time tm;
62 unsigned int save_control; 65 unsigned int save_control;
66 unsigned long flags;
63 67
64 to_tm(tim, &tm); 68 to_tm(tim, &tm);
65 69
@@ -68,6 +72,7 @@ static int indy_rtc_set_time(unsigned long tim)
68 if (tm.tm_year >= 100) 72 if (tm.tm_year >= 100)
69 tm.tm_year -= 100; 73 tm.tm_year -= 100;
70 74
75 spin_lock_irqsave(&rtc_lock, flags);
71 save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; 76 save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
72 hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; 77 hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
73 78
@@ -80,6 +85,7 @@ static int indy_rtc_set_time(unsigned long tim)
80 hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; 85 hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0;
81 86
82 hpc3c0->rtcregs[RTC_CMD] = save_control; 87 hpc3c0->rtcregs[RTC_CMD] = save_control;
88 spin_unlock_irqrestore(&rtc_lock, flags);
83 89
84 return 0; 90 return 0;
85} 91}
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index 5b4fc26c1b36..c13914bdda59 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -144,6 +144,7 @@ static int m41t81_write(uint8_t addr, int b)
144int m41t81_set_time(unsigned long t) 144int m41t81_set_time(unsigned long t)
145{ 145{
146 struct rtc_time tm; 146 struct rtc_time tm;
147 unsigned long flags;
147 148
148 to_tm(t, &tm); 149 to_tm(t, &tm);
149 150
@@ -153,6 +154,7 @@ int m41t81_set_time(unsigned long t)
153 * believe we should finish writing min within a second. 154 * believe we should finish writing min within a second.
154 */ 155 */
155 156
157 spin_lock_irqsave(&rtc_lock, flags);
156 tm.tm_sec = BIN2BCD(tm.tm_sec); 158 tm.tm_sec = BIN2BCD(tm.tm_sec);
157 m41t81_write(M41T81REG_SC, tm.tm_sec); 159 m41t81_write(M41T81REG_SC, tm.tm_sec);
158 160
@@ -180,6 +182,7 @@ int m41t81_set_time(unsigned long t)
180 tm.tm_year %= 100; 182 tm.tm_year %= 100;
181 tm.tm_year = BIN2BCD(tm.tm_year); 183 tm.tm_year = BIN2BCD(tm.tm_year);
182 m41t81_write(M41T81REG_YR, tm.tm_year); 184 m41t81_write(M41T81REG_YR, tm.tm_year);
185 spin_unlock_irqrestore(&rtc_lock, flags);
183 186
184 return 0; 187 return 0;
185} 188}
@@ -187,19 +190,23 @@ int m41t81_set_time(unsigned long t)
187unsigned long m41t81_get_time(void) 190unsigned long m41t81_get_time(void)
188{ 191{
189 unsigned int year, mon, day, hour, min, sec; 192 unsigned int year, mon, day, hour, min, sec;
193 unsigned long flags;
190 194
191 /* 195 /*
192 * min is valid if two reads of sec are the same. 196 * min is valid if two reads of sec are the same.
193 */ 197 */
194 for (;;) { 198 for (;;) {
199 spin_lock_irqsave(&rtc_lock, flags);
195 sec = m41t81_read(M41T81REG_SC); 200 sec = m41t81_read(M41T81REG_SC);
196 min = m41t81_read(M41T81REG_MN); 201 min = m41t81_read(M41T81REG_MN);
197 if (sec == m41t81_read(M41T81REG_SC)) break; 202 if (sec == m41t81_read(M41T81REG_SC)) break;
203 spin_unlock_irqrestore(&rtc_lock, flags);
198 } 204 }
199 hour = m41t81_read(M41T81REG_HR) & 0x3f; 205 hour = m41t81_read(M41T81REG_HR) & 0x3f;
200 day = m41t81_read(M41T81REG_DT); 206 day = m41t81_read(M41T81REG_DT);
201 mon = m41t81_read(M41T81REG_MO); 207 mon = m41t81_read(M41T81REG_MO);
202 year = m41t81_read(M41T81REG_YR); 208 year = m41t81_read(M41T81REG_YR);
209 spin_unlock_irqrestore(&rtc_lock, flags);
203 210
204 sec = BCD2BIN(sec); 211 sec = BCD2BIN(sec);
205 min = BCD2BIN(min); 212 min = BCD2BIN(min);
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index d9ff9323f24e..f4a178836415 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -113,9 +113,11 @@ int xicor_set_time(unsigned long t)
113{ 113{
114 struct rtc_time tm; 114 struct rtc_time tm;
115 int tmp; 115 int tmp;
116 unsigned long flags;
116 117
117 to_tm(t, &tm); 118 to_tm(t, &tm);
118 119
120 spin_lock_irqsave(&rtc_lock, flags);
119 /* unlock writes to the CCR */ 121 /* unlock writes to the CCR */
120 xicor_write(X1241REG_SR, X1241REG_SR_WEL); 122 xicor_write(X1241REG_SR, X1241REG_SR_WEL);
121 xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); 123 xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
@@ -160,6 +162,7 @@ int xicor_set_time(unsigned long t)
160 xicor_write(X1241REG_HR, tmp); 162 xicor_write(X1241REG_HR, tmp);
161 163
162 xicor_write(X1241REG_SR, 0); 164 xicor_write(X1241REG_SR, 0);
165 spin_unlock_irqrestore(&rtc_lock, flags);
163 166
164 return 0; 167 return 0;
165} 168}
@@ -167,7 +170,9 @@ int xicor_set_time(unsigned long t)
167unsigned long xicor_get_time(void) 170unsigned long xicor_get_time(void)
168{ 171{
169 unsigned int year, mon, day, hour, min, sec, y2k; 172 unsigned int year, mon, day, hour, min, sec, y2k;
173 unsigned long flags;
170 174
175 spin_lock_irqsave(&rtc_lock, flags);
171 sec = xicor_read(X1241REG_SC); 176 sec = xicor_read(X1241REG_SC);
172 min = xicor_read(X1241REG_MN); 177 min = xicor_read(X1241REG_MN);
173 hour = xicor_read(X1241REG_HR); 178 hour = xicor_read(X1241REG_HR);
@@ -183,6 +188,7 @@ unsigned long xicor_get_time(void)
183 mon = xicor_read(X1241REG_MO); 188 mon = xicor_read(X1241REG_MO);
184 year = xicor_read(X1241REG_YR); 189 year = xicor_read(X1241REG_YR);
185 y2k = xicor_read(X1241REG_Y2K); 190 y2k = xicor_read(X1241REG_Y2K);
191 spin_unlock_irqrestore(&rtc_lock, flags);
186 192
187 sec = BCD2BIN(sec); 193 sec = BCD2BIN(sec);
188 min = BCD2BIN(min); 194 min = BCD2BIN(min);
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 18130c3748f3..b6fe202a620d 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -78,52 +78,13 @@ void ptrace_disable(struct task_struct *child)
78 pa_psw(child)->l = 0; 78 pa_psw(child)->l = 0;
79} 79}
80 80
81long sys_ptrace(long request, long pid, long addr, long data) 81long arch_ptrace(struct task_struct *child, long request, long addr, long data)
82{ 82{
83 struct task_struct *child;
84 long ret; 83 long ret;
85#ifdef DEBUG_PTRACE 84#ifdef DEBUG_PTRACE
86 long oaddr=addr, odata=data; 85 long oaddr=addr, odata=data;
87#endif 86#endif
88 87
89 lock_kernel();
90 ret = -EPERM;
91 if (request == PTRACE_TRACEME) {
92 /* are we already being traced? */
93 if (current->ptrace & PT_PTRACED)
94 goto out;
95
96 ret = security_ptrace(current->parent, current);
97 if (ret)
98 goto out;
99
100 /* set the ptrace bit in the process flags. */
101 current->ptrace |= PT_PTRACED;
102 ret = 0;
103 goto out;
104 }
105
106 ret = -ESRCH;
107 read_lock(&tasklist_lock);
108 child = find_task_by_pid(pid);
109 if (child)
110 get_task_struct(child);
111 read_unlock(&tasklist_lock);
112 if (!child)
113 goto out;
114 ret = -EPERM;
115 if (pid == 1) /* no messing around with init! */
116 goto out_tsk;
117
118 if (request == PTRACE_ATTACH) {
119 ret = ptrace_attach(child);
120 goto out_tsk;
121 }
122
123 ret = ptrace_check_attach(child, request == PTRACE_KILL);
124 if (ret < 0)
125 goto out_tsk;
126
127 switch (request) { 88 switch (request) {
128 case PTRACE_PEEKTEXT: /* read word at location addr. */ 89 case PTRACE_PEEKTEXT: /* read word at location addr. */
129 case PTRACE_PEEKDATA: { 90 case PTRACE_PEEKDATA: {
@@ -383,11 +344,11 @@ long sys_ptrace(long request, long pid, long addr, long data)
383 344
384 case PTRACE_GETEVENTMSG: 345 case PTRACE_GETEVENTMSG:
385 ret = put_user(child->ptrace_message, (unsigned int __user *) data); 346 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
386 goto out_tsk; 347 goto out;
387 348
388 default: 349 default:
389 ret = ptrace_request(child, request, addr, data); 350 ret = ptrace_request(child, request, addr, data);
390 goto out_tsk; 351 goto out;
391 } 352 }
392 353
393out_wake_notrap: 354out_wake_notrap:
@@ -396,10 +357,7 @@ out_wake:
396 wake_up_process(child); 357 wake_up_process(child);
397 ret = 0; 358 ret = 0;
398out_tsk: 359out_tsk:
399 put_task_struct(child); 360 DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
400out:
401 unlock_kernel();
402 DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
403 request, pid, oaddr, odata, ret); 361 request, pid, oaddr, odata, ret);
404 return ret; 362 return ret;
405} 363}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ca7acb0c79f0..6ffae2d2b3fa 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -605,6 +605,7 @@ config NODES_SPAN_OTHER_NODES
605 605
606config PPC_64K_PAGES 606config PPC_64K_PAGES
607 bool "64k page size" 607 bool "64k page size"
608 depends on PPC64
608 help 609 help
609 This option changes the kernel logical page size to 64k. On machines 610 This option changes the kernel logical page size to 64k. On machines
610 without processor support for 64k pages, the kernel will simulate 611 without processor support for 64k pages, the kernel will simulate
@@ -916,8 +917,21 @@ source "arch/powerpc/platforms/iseries/Kconfig"
916 917
917source "lib/Kconfig" 918source "lib/Kconfig"
918 919
920menu "Instrumentation Support"
921 depends on EXPERIMENTAL
922
919source "arch/powerpc/oprofile/Kconfig" 923source "arch/powerpc/oprofile/Kconfig"
920 924
925config KPROBES
926 bool "Kprobes (EXPERIMENTAL)"
927 help
928 Kprobes allows you to trap at almost any kernel address and
929 execute a callback function. register_kprobe() establishes
930 a probepoint and specifies the callback. Kprobes is useful
931 for kernel debugging, non-intrusive instrumentation and testing.
932 If in doubt, say "N".
933endmenu
934
921source "arch/powerpc/Kconfig.debug" 935source "arch/powerpc/Kconfig.debug"
922 936
923source "security/Kconfig" 937source "security/Kconfig"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 0baf64ec80d0..30a30bf559ea 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -9,16 +9,6 @@ config DEBUG_STACKOVERFLOW
9 This option will cause messages to be printed if free stack space 9 This option will cause messages to be printed if free stack space
10 drops below a certain limit. 10 drops below a certain limit.
11 11
12config KPROBES
13 bool "Kprobes"
14 depends on DEBUG_KERNEL && PPC64
15 help
16 Kprobes allows you to trap at almost any kernel address and
17 execute a callback function. register_kprobe() establishes
18 a probepoint and specifies the callback. Kprobes is useful
19 for kernel debugging, non-intrusive instrumentation and testing.
20 If in doubt, say "N".
21
22config DEBUG_STACK_USAGE 12config DEBUG_STACK_USAGE
23 bool "Stack utilization instrumentation" 13 bool "Stack utilization instrumentation"
24 depends on DEBUG_KERNEL && PPC64 14 depends on DEBUG_KERNEL && PPC64
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 33c63bcf69f8..cc4e9eb1c13f 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -929,6 +929,16 @@ struct cpu_spec cpu_specs[] = {
929 .icache_bsize = 32, 929 .icache_bsize = 32,
930 .dcache_bsize = 32, 930 .dcache_bsize = 32,
931 }, 931 },
932 { /* 440SPe Rev. A */
933 .pvr_mask = 0xff000fff,
934 .pvr_value = 0x53000890,
935 .cpu_name = "440SPe Rev. A",
936 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
937 CPU_FTR_USE_TB,
938 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
939 .icache_bsize = 32,
940 .dcache_bsize = 32,
941 },
932#endif /* CONFIG_44x */ 942#endif /* CONFIG_44x */
933#ifdef CONFIG_FSL_BOOKE 943#ifdef CONFIG_FSL_BOOKE
934 { /* e200z5 */ 944 { /* e200z5 */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 568ea335d616..3d2abd95c7ae 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -248,46 +248,10 @@ void ptrace_disable(struct task_struct *child)
248 clear_single_step(child); 248 clear_single_step(child);
249} 249}
250 250
251long sys_ptrace(long request, long pid, long addr, long data) 251long arch_ptrace(struct task_struct *child, long request, long addr, long data)
252{ 252{
253 struct task_struct *child;
254 int ret = -EPERM; 253 int ret = -EPERM;
255 254
256 lock_kernel();
257 if (request == PTRACE_TRACEME) {
258 /* are we already being traced? */
259 if (current->ptrace & PT_PTRACED)
260 goto out;
261 ret = security_ptrace(current->parent, current);
262 if (ret)
263 goto out;
264 /* set the ptrace bit in the process flags. */
265 current->ptrace |= PT_PTRACED;
266 ret = 0;
267 goto out;
268 }
269 ret = -ESRCH;
270 read_lock(&tasklist_lock);
271 child = find_task_by_pid(pid);
272 if (child)
273 get_task_struct(child);
274 read_unlock(&tasklist_lock);
275 if (!child)
276 goto out;
277
278 ret = -EPERM;
279 if (pid == 1) /* you may not mess with init */
280 goto out_tsk;
281
282 if (request == PTRACE_ATTACH) {
283 ret = ptrace_attach(child);
284 goto out_tsk;
285 }
286
287 ret = ptrace_check_attach(child, request == PTRACE_KILL);
288 if (ret < 0)
289 goto out_tsk;
290
291 switch (request) { 255 switch (request) {
292 /* when I and D space are separate, these will need to be fixed. */ 256 /* when I and D space are separate, these will need to be fixed. */
293 case PTRACE_PEEKTEXT: /* read word at location addr. */ 257 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -540,10 +504,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
540 ret = ptrace_request(child, request, addr, data); 504 ret = ptrace_request(child, request, addr, data);
541 break; 505 break;
542 } 506 }
543out_tsk: 507
544 put_task_struct(child);
545out:
546 unlock_kernel();
547 return ret; 508 return ret;
548} 509}
549 510
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 1c7ea5e06311..a6282b625b44 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -70,6 +70,7 @@
70#include <asm/iseries/it_lp_queue.h> 70#include <asm/iseries/it_lp_queue.h>
71#include <asm/iseries/hv_call_xm.h> 71#include <asm/iseries/hv_call_xm.h>
72#endif 72#endif
73#include <asm/smp.h>
73 74
74/* keep track of when we need to update the rtc */ 75/* keep track of when we need to update the rtc */
75time_t last_rtc_update; 76time_t last_rtc_update;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 37273f518a35..3d83c3b84f0e 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -328,12 +328,14 @@ static void __init htab_init_page_sizes(void)
328 */ 328 */
329 if (mmu_psize_defs[MMU_PAGE_16M].shift) 329 if (mmu_psize_defs[MMU_PAGE_16M].shift)
330 mmu_huge_psize = MMU_PAGE_16M; 330 mmu_huge_psize = MMU_PAGE_16M;
331 /* With 4k/4level pagetables, we can't (for now) cope with a
332 * huge page size < PMD_SIZE */
331 else if (mmu_psize_defs[MMU_PAGE_1M].shift) 333 else if (mmu_psize_defs[MMU_PAGE_1M].shift)
332 mmu_huge_psize = MMU_PAGE_1M; 334 mmu_huge_psize = MMU_PAGE_1M;
333 335
334 /* Calculate HPAGE_SHIFT and sanity check it */ 336 /* Calculate HPAGE_SHIFT and sanity check it */
335 if (mmu_psize_defs[mmu_huge_psize].shift > 16 && 337 if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT &&
336 mmu_psize_defs[mmu_huge_psize].shift < 28) 338 mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT)
337 HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift; 339 HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
338 else 340 else
339 HPAGE_SHIFT = 0; /* No huge pages dude ! */ 341 HPAGE_SHIFT = 0; /* No huge pages dude ! */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0073a04047e4..426c269e552e 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -212,6 +212,12 @@ static int prepare_high_area_for_htlb(struct mm_struct *mm, unsigned long area)
212 212
213 BUG_ON(area >= NUM_HIGH_AREAS); 213 BUG_ON(area >= NUM_HIGH_AREAS);
214 214
215 /* Hack, so that each addresses is controlled by exactly one
216 * of the high or low area bitmaps, the first high area starts
217 * at 4GB, not 0 */
218 if (start == 0)
219 start = 0x100000000UL;
220
215 /* Check no VMAs are in the region */ 221 /* Check no VMAs are in the region */
216 vma = find_vma(mm, start); 222 vma = find_vma(mm, start);
217 if (vma && (vma->vm_start < end)) 223 if (vma && (vma->vm_start < end))
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index d137abd241ff..ed7fcfe5fd37 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -188,9 +188,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
188 188
189 if (Hash == 0) 189 if (Hash == 0)
190 return; 190 return;
191 pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address); 191 pmd = pmd_offset(pgd_offset(mm, ea), ea);
192 if (!pmd_none(*pmd)) 192 if (!pmd_none(*pmd))
193 add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd)); 193 add_hash_page(mm->context, ea, pmd_val(*pmd));
194} 194}
195 195
196/* 196/*
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 3e18241b6f35..950ffc5848c7 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -80,12 +80,17 @@ _GLOBAL(slb_miss_kernel_load_virtual)
80BEGIN_FTR_SECTION 80BEGIN_FTR_SECTION
81 b 1f 81 b 1f
82END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE) 82END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
83 cmpldi r10,16
84
85 lhz r9,PACALOWHTLBAREAS(r13)
86 mr r11,r10
87 blt 5f
88
83 lhz r9,PACAHIGHHTLBAREAS(r13) 89 lhz r9,PACAHIGHHTLBAREAS(r13)
84 srdi r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT) 90 srdi r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT)
85 srd r9,r9,r11 91
86 lhz r11,PACALOWHTLBAREAS(r13) 925: srd r9,r9,r11
87 srd r11,r11,r10 93 andi. r9,r9,1
88 or. r9,r9,r11
89 beq 1f 94 beq 1f
90_GLOBAL(slb_miss_user_load_huge) 95_GLOBAL(slb_miss_user_load_huge)
91 li r11,0 96 li r11,0
diff --git a/arch/powerpc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
index 19d37730b664..eb2dece76a54 100644
--- a/arch/powerpc/oprofile/Kconfig
+++ b/arch/powerpc/oprofile/Kconfig
@@ -1,7 +1,3 @@
1
2menu "Profiling support"
3 depends on EXPERIMENTAL
4
5config PROFILING 1config PROFILING
6 bool "Profiling support (EXPERIMENTAL)" 2 bool "Profiling support (EXPERIMENTAL)"
7 help 3 help
@@ -19,5 +15,3 @@ config OPROFILE
19 15
20 If unsure, say N. 16 If unsure, say N.
21 17
22endmenu
23
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 58c61219d08e..d7d400339458 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -286,10 +286,8 @@ static struct property *new_property(const char *name, const int length,
286 return new; 286 return new;
287 287
288cleanup: 288cleanup:
289 if (new->name) 289 kfree(new->name);
290 kfree(new->name); 290 kfree(new->value);
291 if (new->value)
292 kfree(new->value);
293 kfree(new); 291 kfree(new);
294 return NULL; 292 return NULL;
295} 293}
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index e95c48d57571..84d96b857e4a 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -1145,8 +1145,8 @@ static int set_serial_info(struct SICC_info *info,
1145 info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | 1145 info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
1146 (info->flags & ASYNC_INTERNAL_FLAGS)); 1146 (info->flags & ASYNC_INTERNAL_FLAGS));
1147 state->custom_divisor = new_serial.custom_divisor; 1147 state->custom_divisor = new_serial.custom_divisor;
1148 state->close_delay = new_serial.close_delay * HZ / 100; 1148 state->close_delay = msecs_to_jiffies(10 * new_serial.close_delay);
1149 state->closing_wait = new_serial.closing_wait * HZ / 100; 1149 state->closing_wait = msecs_to_jiffies(10 * new_serial.closing_wait);
1150 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1150 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1151 port->fifosize = new_serial.xmit_fifo_size; 1151 port->fifosize = new_serial.xmit_fifo_size;
1152 1152
@@ -1465,10 +1465,8 @@ static void siccuart_close(struct tty_struct *tty, struct file *filp)
1465 info->event = 0; 1465 info->event = 0;
1466 info->tty = NULL; 1466 info->tty = NULL;
1467 if (info->blocked_open) { 1467 if (info->blocked_open) {
1468 if (info->state->close_delay) { 1468 if (info->state->close_delay)
1469 set_current_state(TASK_INTERRUPTIBLE); 1469 schedule_timeout_interruptible(info->state->close_delay);
1470 schedule_timeout(info->state->close_delay);
1471 }
1472 wake_up_interruptible(&info->open_wait); 1470 wake_up_interruptible(&info->open_wait);
1473 } 1471 }
1474 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 1472 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1496,7 +1494,7 @@ static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
1496 * Note: we have to use pretty tight timings here to satisfy 1494 * Note: we have to use pretty tight timings here to satisfy
1497 * the NIST-PCTS. 1495 * the NIST-PCTS.
1498 */ 1496 */
1499 char_time = (info->timeout - HZ/50) / info->port->fifosize; 1497 char_time = (info->timeout - msecs_to_jiffies(20)) / info->port->fifosize;
1500 char_time = char_time / 5; 1498 char_time = char_time / 5;
1501 if (char_time == 0) 1499 if (char_time == 0)
1502 char_time = 1; 1500 char_time = 1;
@@ -1521,8 +1519,7 @@ static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
1521 tty->index, jiffies, 1519 tty->index, jiffies,
1522 expire, char_time); 1520 expire, char_time);
1523 while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) { 1521 while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) {
1524 set_current_state(TASK_INTERRUPTIBLE); 1522 schedule_timeout_interruptible(char_time);
1525 schedule_timeout(char_time);
1526 if (signal_pending(current)) 1523 if (signal_pending(current))
1527 break; 1524 break;
1528 if (timeout && time_after(jiffies, expire)) 1525 if (timeout && time_after(jiffies, expire))
@@ -1773,7 +1770,7 @@ int __init siccuart_init(void)
1773 for (i = 0; i < SERIAL_SICC_NR; i++) { 1770 for (i = 0; i < SERIAL_SICC_NR; i++) {
1774 struct SICC_state *state = sicc_state + i; 1771 struct SICC_state *state = sicc_state + i;
1775 state->line = i; 1772 state->line = i;
1776 state->close_delay = 5 * HZ / 10; 1773 state->close_delay = msecs_to_jiffies(500);
1777 state->closing_wait = 30 * HZ; 1774 state->closing_wait = 30 * HZ;
1778 spin_lock_init(&state->sicc_lock); 1775 spin_lock_init(&state->sicc_lock);
1779 } 1776 }
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 2086c6ad1147..4edeede9ccfd 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -1309,8 +1309,7 @@ static void mii_dm9161_wait(uint mii_reg, struct net_device *dev)
1309 1309
1310 /* Davicom takes a bit to come up after a reset, 1310 /* Davicom takes a bit to come up after a reset,
1311 * so wait here for a bit */ 1311 * so wait here for a bit */
1312 set_current_state(TASK_UNINTERRUPTIBLE); 1312 schedule_timeout_uninterruptible(timeout);
1313 schedule_timeout(timeout);
1314} 1313}
1315 1314
1316static phy_info_t phy_info_dm9161 = { 1315static phy_info_t phy_info_dm9161 = {
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index 532caa388dc2..49eb2a7e65c0 100644
--- a/arch/ppc/8xx_io/cs4218_tdm.c
+++ b/arch/ppc/8xx_io/cs4218_tdm.c
@@ -1013,8 +1013,7 @@ static void CS_IrqCleanup(void)
1013 */ 1013 */
1014 cpm_free_handler(CPMVEC_SMC2); 1014 cpm_free_handler(CPMVEC_SMC2);
1015 1015
1016 if (beep_buf) 1016 kfree(beep_buf);
1017 kfree(beep_buf);
1018 kd_mksound = orig_mksound; 1017 kd_mksound = orig_mksound;
1019} 1018}
1020#endif /* MODULE */ 1019#endif /* MODULE */
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 114b90fdea24..8fa51b0a32d2 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -746,6 +746,16 @@ config MPC834x
746 bool 746 bool
747 default y if MPC834x_SYS 747 default y if MPC834x_SYS
748 748
749config CPM1
750 bool
751 depends on 8xx
752 default y
753 help
754 The CPM1 (Communications Processor Module) is a coprocessor on
755 embedded CPUs made by Motorola. Selecting this option means that
756 you wish to build a kernel for a machine with a CPM1 coprocessor
757 on it (8xx, 827x, 8560).
758
749config CPM2 759config CPM2
750 bool 760 bool
751 depends on 8260 || MPC8560 || MPC8555 761 depends on 8260 || MPC8560 || MPC8555
@@ -1247,6 +1257,14 @@ source "drivers/pci/Kconfig"
1247 1257
1248source "drivers/pcmcia/Kconfig" 1258source "drivers/pcmcia/Kconfig"
1249 1259
1260config RAPIDIO
1261 bool "RapidIO support" if MPC8540 || MPC8560
1262 help
1263 If you say Y here, the kernel will include drivers and
1264 infrastructure code to support RapidIO interconnect devices.
1265
1266source "drivers/rapidio/Kconfig"
1267
1250endmenu 1268endmenu
1251 1269
1252menu "Advanced setup" 1270menu "Advanced setup"
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index b7bd8f61a4ad..82df88b01bbe 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -67,6 +67,12 @@ zimageinitrd-$(CONFIG_BAMBOO) := zImage.initrd-TREE
67 entrypoint-$(CONFIG_BAMBOO) := 0x01000000 67 entrypoint-$(CONFIG_BAMBOO) := 0x01000000
68 extra.o-$(CONFIG_BAMBOO) := pibs.o 68 extra.o-$(CONFIG_BAMBOO) := pibs.o
69 69
70 zimage-$(CONFIG_BUBINGA) := zImage-TREE
71zimageinitrd-$(CONFIG_BUBINGA) := zImage.initrd-TREE
72 end-$(CONFIG_BUBINGA) := bubinga
73 entrypoint-$(CONFIG_BUBINGA) := 0x01000000
74 extra.o-$(CONFIG_BUBINGA) := openbios.o
75
70 zimage-$(CONFIG_EBONY) := zImage-TREE 76 zimage-$(CONFIG_EBONY) := zImage-TREE
71zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE 77zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE
72 end-$(CONFIG_EBONY) := ebony 78 end-$(CONFIG_EBONY) := ebony
@@ -79,12 +85,30 @@ zimageinitrd-$(CONFIG_LUAN) := zImage.initrd-TREE
79 entrypoint-$(CONFIG_LUAN) := 0x01000000 85 entrypoint-$(CONFIG_LUAN) := 0x01000000
80 extra.o-$(CONFIG_LUAN) := pibs.o 86 extra.o-$(CONFIG_LUAN) := pibs.o
81 87
88 zimage-$(CONFIG_YUCCA) := zImage-TREE
89zimageinitrd-$(CONFIG_YUCCA) := zImage.initrd-TREE
90 end-$(CONFIG_YUCCA) := yucca
91 entrypoint-$(CONFIG_YUCCA) := 0x01000000
92 extra.o-$(CONFIG_YUCCA) := pibs.o
93
82 zimage-$(CONFIG_OCOTEA) := zImage-TREE 94 zimage-$(CONFIG_OCOTEA) := zImage-TREE
83zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE 95zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE
84 end-$(CONFIG_OCOTEA) := ocotea 96 end-$(CONFIG_OCOTEA) := ocotea
85 entrypoint-$(CONFIG_OCOTEA) := 0x01000000 97 entrypoint-$(CONFIG_OCOTEA) := 0x01000000
86 extra.o-$(CONFIG_OCOTEA) := pibs.o 98 extra.o-$(CONFIG_OCOTEA) := pibs.o
87 99
100 zimage-$(CONFIG_SYCAMORE) := zImage-TREE
101zimageinitrd-$(CONFIG_SYCAMORE) := zImage.initrd-TREE
102 end-$(CONFIG_SYCAMORE) := sycamore
103 entrypoint-$(CONFIG_SYCAMORE) := 0x01000000
104 extra.o-$(CONFIG_SYCAMORE) := openbios.o
105
106 zimage-$(CONFIG_WALNUT) := zImage-TREE
107zimageinitrd-$(CONFIG_WALNUT) := zImage.initrd-TREE
108 end-$(CONFIG_WALNUT) := walnut
109 entrypoint-$(CONFIG_WALNUT) := 0x01000000
110 extra.o-$(CONFIG_WALNUT) := openbios.o
111
88 extra.o-$(CONFIG_EV64260) := misc-ev64260.o 112 extra.o-$(CONFIG_EV64260) := misc-ev64260.o
89 end-$(CONFIG_EV64260) := ev64260 113 end-$(CONFIG_EV64260) := ev64260
90 cacheflag-$(CONFIG_EV64260) := -include $(clear_L2_L3) 114 cacheflag-$(CONFIG_EV64260) := -include $(clear_L2_L3)
@@ -162,7 +186,8 @@ OBJCOPY_ARGS := -O elf32-powerpc
162 186
163# head.o and relocate.o must be at the start. 187# head.o and relocate.o must be at the start.
164boot-y := head.o relocate.o $(extra.o-y) $(misc-y) 188boot-y := head.o relocate.o $(extra.o-y) $(misc-y)
165boot-$(CONFIG_40x) += embed_config.o 189boot-$(CONFIG_REDWOOD_5) += embed_config.o
190boot-$(CONFIG_REDWOOD_6) += embed_config.o
166boot-$(CONFIG_8xx) += embed_config.o 191boot-$(CONFIG_8xx) += embed_config.o
167boot-$(CONFIG_8260) += embed_config.o 192boot-$(CONFIG_8260) += embed_config.o
168boot-$(CONFIG_BSEIP) += iic.o 193boot-$(CONFIG_BSEIP) += iic.o
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index e02de5b467a4..f415d6c62362 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -23,7 +23,7 @@
23#include <asm/page.h> 23#include <asm/page.h>
24#include <asm/mmu.h> 24#include <asm/mmu.h>
25#include <asm/bootinfo.h> 25#include <asm/bootinfo.h>
26#ifdef CONFIG_44x 26#ifdef CONFIG_4xx
27#include <asm/ibm4xx.h> 27#include <asm/ibm4xx.h>
28#endif 28#endif
29#include <asm/reg.h> 29#include <asm/reg.h>
@@ -88,6 +88,14 @@ get_mem_size(void)
88 return 0; 88 return 0;
89} 89}
90 90
91#if defined(CONFIG_40x)
92#define PPC4xx_EMAC0_MR0 EMAC0_BASE
93#endif
94
95#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
96#define PPC4xx_EMAC0_MR0 PPC44x_EMAC0_MR0
97#endif
98
91struct bi_record * 99struct bi_record *
92decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) 100decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
93{ 101{
@@ -103,13 +111,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
103 com_port = serial_init(0, NULL); 111 com_port = serial_init(0, NULL);
104#endif 112#endif
105 113
106#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0) 114#if defined(PPC4xx_EMAC0_MR0)
107 /* Reset MAL */ 115 /* Reset MAL */
108 mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); 116 mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
109 /* Wait for reset */ 117 /* Wait for reset */
110 while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; 118 while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {};
111 /* Reset EMAC */ 119 /* Reset EMAC */
112 *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000; 120 *(volatile unsigned long *)PPC4xx_EMAC0_MR0 = 0x20000000;
113 __asm__ __volatile__("eieio"); 121 __asm__ __volatile__("eieio");
114#endif 122#endif
115 123
@@ -164,7 +172,9 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
164 puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); 172 puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
165 } 173 }
166 174
175#ifndef CONFIG_40x /* don't overwrite the 40x image located at 0x00400000! */
167 avail_ram = (char *)0x00400000; 176 avail_ram = (char *)0x00400000;
177#endif
168 end_avail = (char *)0x00800000; 178 end_avail = (char *)0x00800000;
169 puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); 179 puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
170 puthex((unsigned long)end_avail); puts("\n"); 180 puthex((unsigned long)end_avail); puts("\n");
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c
index c732b6d70cfb..81f11d8b30a7 100644
--- a/arch/ppc/boot/simple/openbios.c
+++ b/arch/ppc/boot/simple/openbios.c
@@ -1,19 +1,43 @@
1/* 1/*
2 * arch/ppc/boot/simple/openbios.c 2 * arch/ppc/boot/simple/openbios.c
3 * 3 *
4 * 2005 (c) SYSGO AG - g.jaeger@sysgo.com 4 * Copyright (c) 2005 DENX Software Engineering
5 * Stefan Roese <sr@denx.de>
6 *
7 * Based on original work by
8 * 2005 (c) SYSGO AG - g.jaeger@sysgo.com
9 *
5 * This file is licensed under the terms of the GNU General Public 10 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without 11 * License version 2. This program is licensed "as is" without
7 * any warranty of any kind, whether express or implied. 12 * any warranty of any kind, whether express or implied.
8 * 13 *
9 * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista)
10 */ 14 */
11 15
12#include <linux/types.h> 16#include <linux/types.h>
13#include <linux/config.h> 17#include <linux/config.h>
14#include <linux/string.h> 18#include <linux/string.h>
15#include <asm/ppcboot.h> 19#include <asm/ppcboot.h>
16#include <platforms/4xx/ebony.h> 20#include <asm/ibm4xx.h>
21#include <asm/reg.h>
22#ifdef CONFIG_40x
23#include <asm/io.h>
24#endif
25
26#if defined(CONFIG_BUBINGA)
27#define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */
28#else
29#define BOARD_INFO_VECTOR 0xFFFE0B50
30#endif
31
32#ifdef CONFIG_40x
33/* Supply a default Ethernet address for those eval boards that don't
34 * ship with one. This is an address from the MBX board I have, so
35 * it is unlikely you will find it on your network.
36 */
37static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
38
39extern unsigned long timebase_period_ns;
40#endif /* CONFIG_40x */
17 41
18extern unsigned long decompress_kernel(unsigned long load_addr, int num_words, 42extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
19 unsigned long cksum); 43 unsigned long cksum);
@@ -23,15 +47,85 @@ extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
23bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot"))); 47bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
24bd_t *hold_residual = &hold_resid_buf; 48bd_t *hold_residual = &hold_resid_buf;
25 49
50typedef struct openbios_board_info {
51 unsigned char bi_s_version[4]; /* Version of this structure */
52 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
53 unsigned int bi_memsize; /* DRAM installed, in bytes */
54#ifdef CONFIG_405EP
55 unsigned char bi_enetaddr[2][6]; /* Local Ethernet MAC address */
56#else /* CONFIG_405EP */
57 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
58#endif /* CONFIG_405EP */
59 unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
60 unsigned int bi_intfreq; /* Processor speed, in Hz */
61 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
62 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
63#ifdef CONFIG_405EP
64 unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
65 unsigned int bi_pllouta_freq; /* PLL OUTA speed, in Hz */
66#endif /* CONFIG_405EP */
67} openbios_bd_t;
68
26void * 69void *
27load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, 70load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
28 void *ign1, void *ign2) 71 void *ign1, void *ign2)
29{ 72{
30 decompress_kernel(load_addr, num_words, cksum); 73#ifdef CONFIG_40x
74 openbios_bd_t *openbios_bd = NULL;
75 openbios_bd_t *(*get_board_info)(void) =
76 (openbios_bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
77
78 /*
79 * On 40x platforms we not only need the MAC-addresses, but also the
80 * clocks and memsize. Now try to get all values using the OpenBIOS
81 * "get_board_info()" callback.
82 */
83 if ((openbios_bd = get_board_info()) != NULL) {
84 /*
85 * Copy bd_info from OpenBIOS struct into U-Boot struct
86 * used by kernel
87 */
88 hold_residual->bi_memsize = openbios_bd->bi_memsize;
89 hold_residual->bi_intfreq = openbios_bd->bi_intfreq;
90 hold_residual->bi_busfreq = openbios_bd->bi_busfreq;
91 hold_residual->bi_pci_busfreq = openbios_bd->bi_pci_busfreq;
92 memcpy(hold_residual->bi_pci_enetaddr, openbios_bd->bi_pci_enetaddr, 6);
93#ifdef CONFIG_405EP
94 memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr[0], 6);
95 memcpy(hold_residual->bi_enet1addr, openbios_bd->bi_enetaddr[1], 6);
96 hold_residual->bi_opbfreq = openbios_bd->bi_opb_busfreq;
97 hold_residual->bi_procfreq = openbios_bd->bi_pllouta_freq;
98#else /* CONFIG_405EP */
99 memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr, 6);
100#endif /* CONFIG_405EP */
101 } else {
102 /* Hmmm...better try to stuff some defaults.
103 */
104 hold_residual->bi_memsize = 16 * 1024 * 1024;
105 hold_residual->bi_intfreq = 200000000;
106 hold_residual->bi_busfreq = 100000000;
107 hold_residual->bi_pci_busfreq = 66666666;
108
109 /*
110 * Only supply one mac-address in this fallback
111 */
112 memcpy(hold_residual->bi_enetaddr, (void *)def_enet_addr, 6);
113#ifdef CONFIG_405EP
114 hold_residual->bi_opbfreq = 50000000;
115 hold_residual->bi_procfreq = 200000000;
116#endif /* CONFIG_405EP */
117 }
31 118
119 timebase_period_ns = 1000000000 / hold_residual->bi_intfreq;
120#endif /* CONFIG_40x */
121
122#ifdef CONFIG_440GP
32 /* simply copy the MAC addresses */ 123 /* simply copy the MAC addresses */
33 memcpy(hold_residual->bi_enetaddr, (char *)EBONY_OPENBIOS_MAC_BASE, 6); 124 memcpy(hold_residual->bi_enetaddr, (char *)OPENBIOS_MAC_BASE, 6);
34 memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6); 125 memcpy(hold_residual->bi_enet1addr, (char *)(OPENBIOS_MAC_BASE+OPENBIOS_MAC_OFFSET), 6);
126#endif /* CONFIG_440GP */
127
128 decompress_kernel(load_addr, num_words, cksum);
35 129
36 return (void *)hold_residual; 130 return (void *)hold_residual;
37} 131}
diff --git a/arch/ppc/configs/ev64360_defconfig b/arch/ppc/configs/ev64360_defconfig
index de9bbb791db9..d471e578dcb5 100644
--- a/arch/ppc/configs/ev64360_defconfig
+++ b/arch/ppc/configs/ev64360_defconfig
@@ -1,17 +1,17 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.13-rc5 3# Linux kernel version: 2.6.14
4# Fri Aug 5 15:18:23 2005 4# Fri Oct 28 19:15:34 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y 7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y 8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_HAVE_DEC_LOCK=y
11CONFIG_PPC=y 10CONFIG_PPC=y
12CONFIG_PPC32=y 11CONFIG_PPC32=y
13CONFIG_GENERIC_NVRAM=y 12CONFIG_GENERIC_NVRAM=y
14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y 13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
15 15
16# 16#
17# Code maturity level options 17# Code maturity level options
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
26# General setup 26# General setup
27# 27#
28CONFIG_LOCALVERSION="" 28CONFIG_LOCALVERSION=""
29CONFIG_LOCALVERSION_AUTO=y
29CONFIG_SWAP=y 30CONFIG_SWAP=y
30CONFIG_SYSVIPC=y 31CONFIG_SYSVIPC=y
31CONFIG_POSIX_MQUEUE=y 32CONFIG_POSIX_MQUEUE=y
@@ -35,6 +36,7 @@ CONFIG_SYSCTL=y
35CONFIG_HOTPLUG=y 36CONFIG_HOTPLUG=y
36CONFIG_KOBJECT_UEVENT=y 37CONFIG_KOBJECT_UEVENT=y
37# CONFIG_IKCONFIG is not set 38# CONFIG_IKCONFIG is not set
39CONFIG_INITRAMFS_SOURCE=""
38# CONFIG_EMBEDDED is not set 40# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 41CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_EXTRA_PASS is not set 42# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -74,7 +76,7 @@ CONFIG_TAU=y
74# CONFIG_TAU_AVERAGE is not set 76# CONFIG_TAU_AVERAGE is not set
75# CONFIG_KEXEC is not set 77# CONFIG_KEXEC is not set
76# CONFIG_CPU_FREQ is not set 78# CONFIG_CPU_FREQ is not set
77# CONFIG_PM is not set 79# CONFIG_WANT_EARLY_SERIAL is not set
78CONFIG_PPC_STD_MMU=y 80CONFIG_PPC_STD_MMU=y
79CONFIG_NOT_COHERENT_CACHE=y 81CONFIG_NOT_COHERENT_CACHE=y
80 82
@@ -86,22 +88,18 @@ CONFIG_NOT_COHERENT_CACHE=y
86# CONFIG_KATANA is not set 88# CONFIG_KATANA is not set
87# CONFIG_WILLOW is not set 89# CONFIG_WILLOW is not set
88# CONFIG_CPCI690 is not set 90# CONFIG_CPCI690 is not set
89# CONFIG_PCORE is not set
90# CONFIG_POWERPMC250 is not set 91# CONFIG_POWERPMC250 is not set
91# CONFIG_CHESTNUT is not set 92# CONFIG_CHESTNUT is not set
92# CONFIG_SPRUCE is not set 93# CONFIG_SPRUCE is not set
93# CONFIG_HDPU is not set 94# CONFIG_HDPU is not set
94# CONFIG_EV64260 is not set 95# CONFIG_EV64260 is not set
95# CONFIG_LOPEC is not set 96# CONFIG_LOPEC is not set
96# CONFIG_MCPN765 is not set
97# CONFIG_MVME5100 is not set 97# CONFIG_MVME5100 is not set
98# CONFIG_PPLUS is not set 98# CONFIG_PPLUS is not set
99# CONFIG_PRPMC750 is not set 99# CONFIG_PRPMC750 is not set
100# CONFIG_PRPMC800 is not set 100# CONFIG_PRPMC800 is not set
101# CONFIG_SANDPOINT is not set 101# CONFIG_SANDPOINT is not set
102# CONFIG_RADSTONE_PPC7D is not set 102# CONFIG_RADSTONE_PPC7D is not set
103# CONFIG_ADIR is not set
104# CONFIG_K2 is not set
105# CONFIG_PAL4 is not set 103# CONFIG_PAL4 is not set
106# CONFIG_GEMINI is not set 104# CONFIG_GEMINI is not set
107# CONFIG_EST8260 is not set 105# CONFIG_EST8260 is not set
@@ -138,10 +136,13 @@ CONFIG_FLATMEM_MANUAL=y
138# CONFIG_SPARSEMEM_MANUAL is not set 136# CONFIG_SPARSEMEM_MANUAL is not set
139CONFIG_FLATMEM=y 137CONFIG_FLATMEM=y
140CONFIG_FLAT_NODE_MEM_MAP=y 138CONFIG_FLAT_NODE_MEM_MAP=y
139# CONFIG_SPARSEMEM_STATIC is not set
141CONFIG_BINFMT_ELF=y 140CONFIG_BINFMT_ELF=y
142CONFIG_BINFMT_MISC=y 141CONFIG_BINFMT_MISC=y
143CONFIG_CMDLINE_BOOL=y 142CONFIG_CMDLINE_BOOL=y
144CONFIG_CMDLINE="console=ttyMM0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2" 143CONFIG_CMDLINE="console=ttyMM0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"
144# CONFIG_PM is not set
145# CONFIG_SOFTWARE_SUSPEND is not set
145CONFIG_SECCOMP=y 146CONFIG_SECCOMP=y
146CONFIG_ISA_DMA_API=y 147CONFIG_ISA_DMA_API=y
147 148
@@ -152,7 +153,6 @@ CONFIG_GENERIC_ISA_DMA=y
152CONFIG_PCI=y 153CONFIG_PCI=y
153CONFIG_PCI_DOMAINS=y 154CONFIG_PCI_DOMAINS=y
154# CONFIG_PCI_LEGACY_PROC is not set 155# CONFIG_PCI_LEGACY_PROC is not set
155# CONFIG_PCI_NAMES is not set
156 156
157# 157#
158# PCCARD (PCMCIA/CardBus) support 158# PCCARD (PCMCIA/CardBus) support
@@ -206,14 +206,19 @@ CONFIG_SYN_COOKIES=y
206# CONFIG_INET_ESP is not set 206# CONFIG_INET_ESP is not set
207# CONFIG_INET_IPCOMP is not set 207# CONFIG_INET_IPCOMP is not set
208# CONFIG_INET_TUNNEL is not set 208# CONFIG_INET_TUNNEL is not set
209CONFIG_IP_TCPDIAG=y 209CONFIG_INET_DIAG=y
210# CONFIG_IP_TCPDIAG_IPV6 is not set 210CONFIG_INET_TCP_DIAG=y
211# CONFIG_TCP_CONG_ADVANCED is not set 211# CONFIG_TCP_CONG_ADVANCED is not set
212CONFIG_TCP_CONG_BIC=y 212CONFIG_TCP_CONG_BIC=y
213# CONFIG_IPV6 is not set 213# CONFIG_IPV6 is not set
214# CONFIG_NETFILTER is not set 214# CONFIG_NETFILTER is not set
215 215
216# 216#
217# DCCP Configuration (EXPERIMENTAL)
218#
219# CONFIG_IP_DCCP is not set
220
221#
217# SCTP Configuration (EXPERIMENTAL) 222# SCTP Configuration (EXPERIMENTAL)
218# 223#
219# CONFIG_IP_SCTP is not set 224# CONFIG_IP_SCTP is not set
@@ -239,6 +244,7 @@ CONFIG_TCP_CONG_BIC=y
239# CONFIG_HAMRADIO is not set 244# CONFIG_HAMRADIO is not set
240# CONFIG_IRDA is not set 245# CONFIG_IRDA is not set
241# CONFIG_BT is not set 246# CONFIG_BT is not set
247# CONFIG_IEEE80211 is not set
242 248
243# 249#
244# Device Drivers 250# Device Drivers
@@ -252,6 +258,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
252# CONFIG_FW_LOADER is not set 258# CONFIG_FW_LOADER is not set
253 259
254# 260#
261# Connector - unified userspace <-> kernelspace linker
262#
263# CONFIG_CONNECTOR is not set
264
265#
255# Memory Technology Devices (MTD) 266# Memory Technology Devices (MTD)
256# 267#
257CONFIG_MTD=y 268CONFIG_MTD=y
@@ -358,7 +369,6 @@ CONFIG_BLK_DEV_RAM=y
358CONFIG_BLK_DEV_RAM_COUNT=16 369CONFIG_BLK_DEV_RAM_COUNT=16
359CONFIG_BLK_DEV_RAM_SIZE=32768 370CONFIG_BLK_DEV_RAM_SIZE=32768
360CONFIG_BLK_DEV_INITRD=y 371CONFIG_BLK_DEV_INITRD=y
361CONFIG_INITRAMFS_SOURCE=""
362# CONFIG_LBD is not set 372# CONFIG_LBD is not set
363# CONFIG_CDROM_PKTCDVD is not set 373# CONFIG_CDROM_PKTCDVD is not set
364 374
@@ -379,6 +389,7 @@ CONFIG_IOSCHED_CFQ=y
379# 389#
380# SCSI device support 390# SCSI device support
381# 391#
392# CONFIG_RAID_ATTRS is not set
382# CONFIG_SCSI is not set 393# CONFIG_SCSI is not set
383 394
384# 395#
@@ -420,6 +431,10 @@ CONFIG_NETDEVICES=y
420# CONFIG_ARCNET is not set 431# CONFIG_ARCNET is not set
421 432
422# 433#
434# PHY device support
435#
436
437#
423# Ethernet (10 or 100Mbit) 438# Ethernet (10 or 100Mbit)
424# 439#
425# CONFIG_NET_ETHERNET is not set 440# CONFIG_NET_ETHERNET is not set
@@ -434,6 +449,7 @@ CONFIG_NETDEVICES=y
434# CONFIG_HAMACHI is not set 449# CONFIG_HAMACHI is not set
435# CONFIG_YELLOWFIN is not set 450# CONFIG_YELLOWFIN is not set
436# CONFIG_R8169 is not set 451# CONFIG_R8169 is not set
452# CONFIG_SIS190 is not set
437# CONFIG_SKGE is not set 453# CONFIG_SKGE is not set
438# CONFIG_SK98LIN is not set 454# CONFIG_SK98LIN is not set
439# CONFIG_TIGON3 is not set 455# CONFIG_TIGON3 is not set
@@ -446,6 +462,7 @@ CONFIG_MV643XX_ETH_0=y
446# 462#
447# Ethernet (10000 Mbit) 463# Ethernet (10000 Mbit)
448# 464#
465# CONFIG_CHELSIO_T1 is not set
449# CONFIG_IXGB is not set 466# CONFIG_IXGB is not set
450# CONFIG_S2IO is not set 467# CONFIG_S2IO is not set
451 468
@@ -547,7 +564,20 @@ CONFIG_LEGACY_PTY_COUNT=256
547# 564#
548# Watchdog Cards 565# Watchdog Cards
549# 566#
550# CONFIG_WATCHDOG is not set 567CONFIG_WATCHDOG=y
568# CONFIG_WATCHDOG_NOWAYOUT is not set
569
570#
571# Watchdog Device Drivers
572#
573# CONFIG_SOFT_WATCHDOG is not set
574CONFIG_MV64X60_WDT=y
575
576#
577# PCI-based Watchdog Cards
578#
579# CONFIG_PCIPCWATCHDOG is not set
580# CONFIG_WDTPCI is not set
551# CONFIG_NVRAM is not set 581# CONFIG_NVRAM is not set
552CONFIG_GEN_RTC=y 582CONFIG_GEN_RTC=y
553# CONFIG_GEN_RTC_X is not set 583# CONFIG_GEN_RTC_X is not set
@@ -571,7 +601,6 @@ CONFIG_GEN_RTC=y
571# I2C support 601# I2C support
572# 602#
573# CONFIG_I2C is not set 603# CONFIG_I2C is not set
574# CONFIG_I2C_SENSOR is not set
575 604
576# 605#
577# Dallas's 1-wire bus 606# Dallas's 1-wire bus
@@ -582,6 +611,7 @@ CONFIG_GEN_RTC=y
582# Hardware Monitoring support 611# Hardware Monitoring support
583# 612#
584CONFIG_HWMON=y 613CONFIG_HWMON=y
614# CONFIG_HWMON_VID is not set
585# CONFIG_HWMON_DEBUG_CHIP is not set 615# CONFIG_HWMON_DEBUG_CHIP is not set
586 616
587# 617#
@@ -589,6 +619,10 @@ CONFIG_HWMON=y
589# 619#
590 620
591# 621#
622# Multimedia Capabilities Port drivers
623#
624
625#
592# Multimedia devices 626# Multimedia devices
593# 627#
594# CONFIG_VIDEO_DEV is not set 628# CONFIG_VIDEO_DEV is not set
@@ -651,10 +685,6 @@ CONFIG_EXT2_FS=y
651# CONFIG_REISERFS_FS is not set 685# CONFIG_REISERFS_FS is not set
652# CONFIG_JFS_FS is not set 686# CONFIG_JFS_FS is not set
653# CONFIG_FS_POSIX_ACL is not set 687# CONFIG_FS_POSIX_ACL is not set
654
655#
656# XFS support
657#
658# CONFIG_XFS_FS is not set 688# CONFIG_XFS_FS is not set
659# CONFIG_MINIX_FS is not set 689# CONFIG_MINIX_FS is not set
660# CONFIG_ROMFS_FS is not set 690# CONFIG_ROMFS_FS is not set
@@ -663,6 +693,7 @@ CONFIG_INOTIFY=y
663CONFIG_DNOTIFY=y 693CONFIG_DNOTIFY=y
664# CONFIG_AUTOFS_FS is not set 694# CONFIG_AUTOFS_FS is not set
665# CONFIG_AUTOFS4_FS is not set 695# CONFIG_AUTOFS4_FS is not set
696# CONFIG_FUSE_FS is not set
666 697
667# 698#
668# CD-ROM/DVD Filesystems 699# CD-ROM/DVD Filesystems
@@ -683,11 +714,10 @@ CONFIG_DNOTIFY=y
683CONFIG_PROC_FS=y 714CONFIG_PROC_FS=y
684CONFIG_PROC_KCORE=y 715CONFIG_PROC_KCORE=y
685CONFIG_SYSFS=y 716CONFIG_SYSFS=y
686# CONFIG_DEVPTS_FS_XATTR is not set
687CONFIG_TMPFS=y 717CONFIG_TMPFS=y
688# CONFIG_TMPFS_XATTR is not set
689# CONFIG_HUGETLB_PAGE is not set 718# CONFIG_HUGETLB_PAGE is not set
690CONFIG_RAMFS=y 719CONFIG_RAMFS=y
720# CONFIG_RELAYFS_FS is not set
691 721
692# 722#
693# Miscellaneous filesystems 723# Miscellaneous filesystems
@@ -735,6 +765,7 @@ CONFIG_SUNRPC=y
735# CONFIG_NCP_FS is not set 765# CONFIG_NCP_FS is not set
736# CONFIG_CODA_FS is not set 766# CONFIG_CODA_FS is not set
737# CONFIG_AFS_FS is not set 767# CONFIG_AFS_FS is not set
768# CONFIG_9P_FS is not set
738 769
739# 770#
740# Partition Types 771# Partition Types
@@ -751,6 +782,7 @@ CONFIG_MSDOS_PARTITION=y
751# Library routines 782# Library routines
752# 783#
753# CONFIG_CRC_CCITT is not set 784# CONFIG_CRC_CCITT is not set
785# CONFIG_CRC16 is not set
754CONFIG_CRC32=y 786CONFIG_CRC32=y
755# CONFIG_LIBCRC32C is not set 787# CONFIG_LIBCRC32C is not set
756CONFIG_ZLIB_INFLATE=y 788CONFIG_ZLIB_INFLATE=y
@@ -767,6 +799,7 @@ CONFIG_ZLIB_DEFLATE=y
767# CONFIG_PRINTK_TIME is not set 799# CONFIG_PRINTK_TIME is not set
768# CONFIG_DEBUG_KERNEL is not set 800# CONFIG_DEBUG_KERNEL is not set
769CONFIG_LOG_BUF_SHIFT=14 801CONFIG_LOG_BUF_SHIFT=14
802# CONFIG_SERIAL_TEXT_DEBUG is not set
770 803
771# 804#
772# Security options 805# Security options
diff --git a/arch/ppc/configs/stx_gp3_defconfig b/arch/ppc/configs/stx_gp3_defconfig
index 66dae8367659..3fedc43e44ad 100644
--- a/arch/ppc/configs/stx_gp3_defconfig
+++ b/arch/ppc/configs/stx_gp3_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc2 3# Linux kernel version: 2.6.12-rc4
4# Wed Jan 26 14:32:58 2005 4# Tue May 24 18:11:04 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y 7CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
11CONFIG_PPC=y 11CONFIG_PPC=y
12CONFIG_PPC32=y 12CONFIG_PPC32=y
13CONFIG_GENERIC_NVRAM=y 13CONFIG_GENERIC_NVRAM=y
14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14 15
15# 16#
16# Code maturity level options 17# Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
18CONFIG_EXPERIMENTAL=y 19CONFIG_EXPERIMENTAL=y
19CONFIG_CLEAN_COMPILE=y 20CONFIG_CLEAN_COMPILE=y
20CONFIG_BROKEN_ON_SMP=y 21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
21 23
22# 24#
23# General setup 25# General setup
@@ -29,7 +31,6 @@ CONFIG_SYSVIPC=y
29# CONFIG_BSD_PROCESS_ACCT is not set 31# CONFIG_BSD_PROCESS_ACCT is not set
30CONFIG_SYSCTL=y 32CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set 33# CONFIG_AUDIT is not set
32CONFIG_LOG_BUF_SHIFT=14
33CONFIG_HOTPLUG=y 34CONFIG_HOTPLUG=y
34CONFIG_KOBJECT_UEVENT=y 35CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set 36# CONFIG_IKCONFIG is not set
@@ -37,6 +38,9 @@ CONFIG_EMBEDDED=y
37CONFIG_KALLSYMS=y 38CONFIG_KALLSYMS=y
38# CONFIG_KALLSYMS_ALL is not set 39# CONFIG_KALLSYMS_ALL is not set
39# CONFIG_KALLSYMS_EXTRA_PASS is not set 40# CONFIG_KALLSYMS_EXTRA_PASS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
40CONFIG_FUTEX=y 44CONFIG_FUTEX=y
41CONFIG_EPOLL=y 45CONFIG_EPOLL=y
42# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -46,6 +50,7 @@ CONFIG_CC_ALIGN_LABELS=0
46CONFIG_CC_ALIGN_LOOPS=0 50CONFIG_CC_ALIGN_LOOPS=0
47CONFIG_CC_ALIGN_JUMPS=0 51CONFIG_CC_ALIGN_JUMPS=0
48# CONFIG_TINY_SHMEM is not set 52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
49 54
50# 55#
51# Loadable module support 56# Loadable module support
@@ -69,9 +74,11 @@ CONFIG_KMOD=y
69CONFIG_E500=y 74CONFIG_E500=y
70CONFIG_BOOKE=y 75CONFIG_BOOKE=y
71CONFIG_FSL_BOOKE=y 76CONFIG_FSL_BOOKE=y
77# CONFIG_PHYS_64BIT is not set
72# CONFIG_SPE is not set 78# CONFIG_SPE is not set
73CONFIG_MATH_EMULATION=y 79CONFIG_MATH_EMULATION=y
74# CONFIG_CPU_FREQ is not set 80# CONFIG_CPU_FREQ is not set
81# CONFIG_PM is not set
75CONFIG_85xx=y 82CONFIG_85xx=y
76CONFIG_PPC_INDIRECT_PCI_BE=y 83CONFIG_PPC_INDIRECT_PCI_BE=y
77 84
@@ -96,6 +103,7 @@ CONFIG_HIGHMEM=y
96CONFIG_BINFMT_ELF=y 103CONFIG_BINFMT_ELF=y
97CONFIG_BINFMT_MISC=m 104CONFIG_BINFMT_MISC=m
98# CONFIG_CMDLINE_BOOL is not set 105# CONFIG_CMDLINE_BOOL is not set
106CONFIG_ISA_DMA_API=y
99 107
100# 108#
101# Bus options 109# Bus options
@@ -104,15 +112,15 @@ CONFIG_PCI=y
104CONFIG_PCI_DOMAINS=y 112CONFIG_PCI_DOMAINS=y
105# CONFIG_PCI_LEGACY_PROC is not set 113# CONFIG_PCI_LEGACY_PROC is not set
106# CONFIG_PCI_NAMES is not set 114# CONFIG_PCI_NAMES is not set
115# CONFIG_PCI_DEBUG is not set
107 116
108# 117#
109# PCCARD (PCMCIA/CardBus) support 118# PCCARD (PCMCIA/CardBus) support
110# 119#
111# CONFIG_PCCARD is not set 120# CONFIG_PCCARD is not set
112 121CONFIG_RAPIDIO=y
113# 122CONFIG_RAPIDIO_8_BIT_TRANSPORT=y
114# PC-card bridges 123CONFIG_RAPIDIO_DISC_TIMEOUT=30
115#
116 124
117# 125#
118# Advanced setup 126# Advanced setup
@@ -152,7 +160,7 @@ CONFIG_PARPORT=m
152CONFIG_PARPORT_PC=m 160CONFIG_PARPORT_PC=m
153# CONFIG_PARPORT_PC_FIFO is not set 161# CONFIG_PARPORT_PC_FIFO is not set
154# CONFIG_PARPORT_PC_SUPERIO is not set 162# CONFIG_PARPORT_PC_SUPERIO is not set
155# CONFIG_PARPORT_OTHER is not set 163# CONFIG_PARPORT_GSC is not set
156# CONFIG_PARPORT_1284 is not set 164# CONFIG_PARPORT_1284 is not set
157 165
158# 166#
@@ -264,7 +272,6 @@ CONFIG_SCSI_CONSTANTS=y
264# CONFIG_SCSI_BUSLOGIC is not set 272# CONFIG_SCSI_BUSLOGIC is not set
265# CONFIG_SCSI_DMX3191D is not set 273# CONFIG_SCSI_DMX3191D is not set
266# CONFIG_SCSI_EATA is not set 274# CONFIG_SCSI_EATA is not set
267# CONFIG_SCSI_EATA_PIO is not set
268# CONFIG_SCSI_FUTURE_DOMAIN is not set 275# CONFIG_SCSI_FUTURE_DOMAIN is not set
269# CONFIG_SCSI_GDTH is not set 276# CONFIG_SCSI_GDTH is not set
270# CONFIG_SCSI_IPS is not set 277# CONFIG_SCSI_IPS is not set
@@ -274,7 +281,6 @@ CONFIG_SCSI_CONSTANTS=y
274# CONFIG_SCSI_IMM is not set 281# CONFIG_SCSI_IMM is not set
275# CONFIG_SCSI_SYM53C8XX_2 is not set 282# CONFIG_SCSI_SYM53C8XX_2 is not set
276# CONFIG_SCSI_IPR is not set 283# CONFIG_SCSI_IPR is not set
277# CONFIG_SCSI_QLOGIC_ISP is not set
278# CONFIG_SCSI_QLOGIC_FC is not set 284# CONFIG_SCSI_QLOGIC_FC is not set
279# CONFIG_SCSI_QLOGIC_1280 is not set 285# CONFIG_SCSI_QLOGIC_1280 is not set
280CONFIG_SCSI_QLA2XXX=m 286CONFIG_SCSI_QLA2XXX=m
@@ -283,6 +289,7 @@ CONFIG_SCSI_QLA2XXX=m
283# CONFIG_SCSI_QLA2300 is not set 289# CONFIG_SCSI_QLA2300 is not set
284# CONFIG_SCSI_QLA2322 is not set 290# CONFIG_SCSI_QLA2322 is not set
285# CONFIG_SCSI_QLA6312 is not set 291# CONFIG_SCSI_QLA6312 is not set
292# CONFIG_SCSI_LPFC is not set
286# CONFIG_SCSI_DC395x is not set 293# CONFIG_SCSI_DC395x is not set
287# CONFIG_SCSI_DC390T is not set 294# CONFIG_SCSI_DC390T is not set
288# CONFIG_SCSI_NSP32 is not set 295# CONFIG_SCSI_NSP32 is not set
@@ -322,7 +329,6 @@ CONFIG_NET=y
322# 329#
323CONFIG_PACKET=y 330CONFIG_PACKET=y
324# CONFIG_PACKET_MMAP is not set 331# CONFIG_PACKET_MMAP is not set
325# CONFIG_NETLINK_DEV is not set
326CONFIG_UNIX=y 332CONFIG_UNIX=y
327# CONFIG_NET_KEY is not set 333# CONFIG_NET_KEY is not set
328CONFIG_INET=y 334CONFIG_INET=y
@@ -431,7 +437,7 @@ CONFIG_IP_NF_NAT_FTP=m
431# 437#
432# Network testing 438# Network testing
433# 439#
434# CONFIG_NET_PKTGEN is not set 440CONFIG_NET_PKTGEN=y
435# CONFIG_NETPOLL is not set 441# CONFIG_NETPOLL is not set
436# CONFIG_NET_POLL_CONTROLLER is not set 442# CONFIG_NET_POLL_CONTROLLER is not set
437# CONFIG_HAMRADIO is not set 443# CONFIG_HAMRADIO is not set
@@ -499,6 +505,7 @@ CONFIG_GFAR_NAPI=y
499# Wan interfaces 505# Wan interfaces
500# 506#
501# CONFIG_WAN is not set 507# CONFIG_WAN is not set
508CONFIG_RIONET=y
502# CONFIG_FDDI is not set 509# CONFIG_FDDI is not set
503# CONFIG_HIPPI is not set 510# CONFIG_HIPPI is not set
504# CONFIG_PLIP is not set 511# CONFIG_PLIP is not set
@@ -536,20 +543,6 @@ CONFIG_INPUT_EVDEV=m
536# CONFIG_INPUT_EVBUG is not set 543# CONFIG_INPUT_EVBUG is not set
537 544
538# 545#
539# Input I/O drivers
540#
541# CONFIG_GAMEPORT is not set
542CONFIG_SOUND_GAMEPORT=y
543CONFIG_SERIO=y
544CONFIG_SERIO_I8042=y
545CONFIG_SERIO_SERPORT=y
546# CONFIG_SERIO_CT82C710 is not set
547# CONFIG_SERIO_PARKBD is not set
548# CONFIG_SERIO_PCIPS2 is not set
549CONFIG_SERIO_LIBPS2=y
550# CONFIG_SERIO_RAW is not set
551
552#
553# Input Device Drivers 546# Input Device Drivers
554# 547#
555CONFIG_INPUT_KEYBOARD=y 548CONFIG_INPUT_KEYBOARD=y
@@ -567,6 +560,19 @@ CONFIG_MOUSE_PS2=y
567# CONFIG_INPUT_MISC is not set 560# CONFIG_INPUT_MISC is not set
568 561
569# 562#
563# Hardware I/O ports
564#
565CONFIG_SERIO=y
566CONFIG_SERIO_I8042=y
567CONFIG_SERIO_SERPORT=y
568# CONFIG_SERIO_PARKBD is not set
569# CONFIG_SERIO_PCIPS2 is not set
570CONFIG_SERIO_LIBPS2=y
571# CONFIG_SERIO_RAW is not set
572# CONFIG_GAMEPORT is not set
573CONFIG_SOUND_GAMEPORT=y
574
575#
570# Character devices 576# Character devices
571# 577#
572# CONFIG_VT is not set 578# CONFIG_VT is not set
@@ -590,6 +596,7 @@ CONFIG_SERIAL_CPM_SCC2=y
590# CONFIG_SERIAL_CPM_SCC4 is not set 596# CONFIG_SERIAL_CPM_SCC4 is not set
591# CONFIG_SERIAL_CPM_SMC1 is not set 597# CONFIG_SERIAL_CPM_SMC1 is not set
592# CONFIG_SERIAL_CPM_SMC2 is not set 598# CONFIG_SERIAL_CPM_SMC2 is not set
599# CONFIG_SERIAL_JSM is not set
593CONFIG_UNIX98_PTYS=y 600CONFIG_UNIX98_PTYS=y
594CONFIG_LEGACY_PTYS=y 601CONFIG_LEGACY_PTYS=y
595CONFIG_LEGACY_PTY_COUNT=256 602CONFIG_LEGACY_PTY_COUNT=256
@@ -626,6 +633,11 @@ CONFIG_DRM=m
626# CONFIG_RAW_DRIVER is not set 633# CONFIG_RAW_DRIVER is not set
627 634
628# 635#
636# TPM devices
637#
638# CONFIG_TCG_TPM is not set
639
640#
629# I2C support 641# I2C support
630# 642#
631CONFIG_I2C=m 643CONFIG_I2C=m
@@ -648,12 +660,12 @@ CONFIG_I2C_ALGOBIT=m
648# CONFIG_I2C_AMD8111 is not set 660# CONFIG_I2C_AMD8111 is not set
649# CONFIG_I2C_I801 is not set 661# CONFIG_I2C_I801 is not set
650# CONFIG_I2C_I810 is not set 662# CONFIG_I2C_I810 is not set
663# CONFIG_I2C_PIIX4 is not set
651# CONFIG_I2C_ISA is not set 664# CONFIG_I2C_ISA is not set
652# CONFIG_I2C_MPC is not set 665# CONFIG_I2C_MPC is not set
653# CONFIG_I2C_NFORCE2 is not set 666# CONFIG_I2C_NFORCE2 is not set
654# CONFIG_I2C_PARPORT is not set 667# CONFIG_I2C_PARPORT is not set
655# CONFIG_I2C_PARPORT_LIGHT is not set 668# CONFIG_I2C_PARPORT_LIGHT is not set
656# CONFIG_I2C_PIIX4 is not set
657# CONFIG_I2C_PROSAVAGE is not set 669# CONFIG_I2C_PROSAVAGE is not set
658# CONFIG_I2C_SAVAGE4 is not set 670# CONFIG_I2C_SAVAGE4 is not set
659# CONFIG_SCx200_ACB is not set 671# CONFIG_SCx200_ACB is not set
@@ -677,7 +689,9 @@ CONFIG_I2C_ALGOBIT=m
677# CONFIG_SENSORS_ASB100 is not set 689# CONFIG_SENSORS_ASB100 is not set
678# CONFIG_SENSORS_DS1621 is not set 690# CONFIG_SENSORS_DS1621 is not set
679# CONFIG_SENSORS_FSCHER is not set 691# CONFIG_SENSORS_FSCHER is not set
692# CONFIG_SENSORS_FSCPOS is not set
680# CONFIG_SENSORS_GL518SM is not set 693# CONFIG_SENSORS_GL518SM is not set
694# CONFIG_SENSORS_GL520SM is not set
681# CONFIG_SENSORS_IT87 is not set 695# CONFIG_SENSORS_IT87 is not set
682# CONFIG_SENSORS_LM63 is not set 696# CONFIG_SENSORS_LM63 is not set
683# CONFIG_SENSORS_LM75 is not set 697# CONFIG_SENSORS_LM75 is not set
@@ -688,9 +702,11 @@ CONFIG_I2C_ALGOBIT=m
688# CONFIG_SENSORS_LM85 is not set 702# CONFIG_SENSORS_LM85 is not set
689# CONFIG_SENSORS_LM87 is not set 703# CONFIG_SENSORS_LM87 is not set
690# CONFIG_SENSORS_LM90 is not set 704# CONFIG_SENSORS_LM90 is not set
705# CONFIG_SENSORS_LM92 is not set
691# CONFIG_SENSORS_MAX1619 is not set 706# CONFIG_SENSORS_MAX1619 is not set
692# CONFIG_SENSORS_PC87360 is not set 707# CONFIG_SENSORS_PC87360 is not set
693# CONFIG_SENSORS_SMSC47B397 is not set 708# CONFIG_SENSORS_SMSC47B397 is not set
709# CONFIG_SENSORS_SIS5595 is not set
694# CONFIG_SENSORS_SMSC47M1 is not set 710# CONFIG_SENSORS_SMSC47M1 is not set
695# CONFIG_SENSORS_VIA686A is not set 711# CONFIG_SENSORS_VIA686A is not set
696# CONFIG_SENSORS_W83781D is not set 712# CONFIG_SENSORS_W83781D is not set
@@ -700,10 +716,12 @@ CONFIG_I2C_ALGOBIT=m
700# 716#
701# Other I2C Chip support 717# Other I2C Chip support
702# 718#
719# CONFIG_SENSORS_DS1337 is not set
703# CONFIG_SENSORS_EEPROM is not set 720# CONFIG_SENSORS_EEPROM is not set
704# CONFIG_SENSORS_PCF8574 is not set 721# CONFIG_SENSORS_PCF8574 is not set
705# CONFIG_SENSORS_PCF8591 is not set 722# CONFIG_SENSORS_PCF8591 is not set
706# CONFIG_SENSORS_RTC8564 is not set 723# CONFIG_SENSORS_RTC8564 is not set
724# CONFIG_SENSORS_M41T00 is not set
707# CONFIG_I2C_DEBUG_CORE is not set 725# CONFIG_I2C_DEBUG_CORE is not set
708# CONFIG_I2C_DEBUG_ALGO is not set 726# CONFIG_I2C_DEBUG_ALGO is not set
709# CONFIG_I2C_DEBUG_BUS is not set 727# CONFIG_I2C_DEBUG_BUS is not set
@@ -732,7 +750,6 @@ CONFIG_I2C_ALGOBIT=m
732# Graphics support 750# Graphics support
733# 751#
734# CONFIG_FB is not set 752# CONFIG_FB is not set
735# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
736 753
737# 754#
738# Sound 755# Sound
@@ -752,13 +769,9 @@ CONFIG_SOUND=m
752# 769#
753# USB support 770# USB support
754# 771#
755# CONFIG_USB is not set
756CONFIG_USB_ARCH_HAS_HCD=y 772CONFIG_USB_ARCH_HAS_HCD=y
757CONFIG_USB_ARCH_HAS_OHCI=y 773CONFIG_USB_ARCH_HAS_OHCI=y
758 774# CONFIG_USB is not set
759#
760# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
761#
762 775
763# 776#
764# USB Gadget Support 777# USB Gadget Support
@@ -789,6 +802,10 @@ CONFIG_JBD_DEBUG=y
789CONFIG_FS_MBCACHE=y 802CONFIG_FS_MBCACHE=y
790# CONFIG_REISERFS_FS is not set 803# CONFIG_REISERFS_FS is not set
791# CONFIG_JFS_FS is not set 804# CONFIG_JFS_FS is not set
805
806#
807# XFS support
808#
792# CONFIG_XFS_FS is not set 809# CONFIG_XFS_FS is not set
793# CONFIG_MINIX_FS is not set 810# CONFIG_MINIX_FS is not set
794# CONFIG_ROMFS_FS is not set 811# CONFIG_ROMFS_FS is not set
@@ -859,7 +876,6 @@ CONFIG_NFS_V3=y
859CONFIG_ROOT_NFS=y 876CONFIG_ROOT_NFS=y
860CONFIG_LOCKD=y 877CONFIG_LOCKD=y
861CONFIG_LOCKD_V4=y 878CONFIG_LOCKD_V4=y
862# CONFIG_EXPORTFS is not set
863CONFIG_SUNRPC=y 879CONFIG_SUNRPC=y
864# CONFIG_RPCSEC_GSS_KRB5 is not set 880# CONFIG_RPCSEC_GSS_KRB5 is not set
865# CONFIG_RPCSEC_GSS_SPKM3 is not set 881# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -942,8 +958,10 @@ CONFIG_ZLIB_INFLATE=m
942# 958#
943# Kernel hacking 959# Kernel hacking
944# 960#
961# CONFIG_PRINTK_TIME is not set
945CONFIG_DEBUG_KERNEL=y 962CONFIG_DEBUG_KERNEL=y
946# CONFIG_MAGIC_SYSRQ is not set 963# CONFIG_MAGIC_SYSRQ is not set
964CONFIG_LOG_BUF_SHIFT=14
947# CONFIG_SCHEDSTATS is not set 965# CONFIG_SCHEDSTATS is not set
948# CONFIG_DEBUG_SLAB is not set 966# CONFIG_DEBUG_SLAB is not set
949# CONFIG_DEBUG_SPINLOCK is not set 967# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index c610ca933a25..76a55a438f23 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_POWER4) += cpu_setup_power4.o
22obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o 22obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
23obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o 23obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
24obj-$(CONFIG_PCI) += pci.o 24obj-$(CONFIG_PCI) += pci.o
25obj-$(CONFIG_RAPIDIO) += rio.o
25obj-$(CONFIG_KGDB) += ppc-stub.o 26obj-$(CONFIG_KGDB) += ppc-stub.o
26obj-$(CONFIG_SMP) += smp.o smp-tbsync.o 27obj-$(CONFIG_SMP) += smp.o smp-tbsync.o
27obj-$(CONFIG_TAU) += temp.o 28obj-$(CONFIG_TAU) += temp.o
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 8b49679fad54..677c571aa276 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -190,8 +190,8 @@ skpinv: addi r4,r4,1 /* Increment */
190 190
191 /* xlat fields */ 191 /* xlat fields */
192 lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ 192 lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
193#ifndef CONFIG_440EP 193#ifdef UART0_PHYS_ERPN
194 ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ 194 ori r4,r4,UART0_PHYS_ERPN /* Add ERPN if above 4GB */
195#endif 195#endif
196 196
197 /* attrib fields */ 197 /* attrib fields */
diff --git a/arch/ppc/kernel/rio.c b/arch/ppc/kernel/rio.c
new file mode 100644
index 000000000000..29487fedfc76
--- /dev/null
+++ b/arch/ppc/kernel/rio.c
@@ -0,0 +1,52 @@
1/*
2 * RapidIO PPC32 support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/rio.h>
16
17#include <asm/rio.h>
18
19/**
20 * platform_rio_init - Do platform specific RIO init
21 *
22 * Any platform specific initialization of RapdIO
23 * hardware is done here as well as registration
24 * of any active master ports in the system.
25 */
26void __attribute__ ((weak))
27 platform_rio_init(void)
28{
29 printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
30}
31
32/**
33 * ppc_rio_init - Do PPC32 RIO init
34 *
35 * Calls platform-specific RIO init code and then calls
36 * rio_init_mports() to initialize any master ports that
37 * have been registered with the RIO subsystem.
38 */
39static int __init ppc_rio_init(void)
40{
41 printk(KERN_INFO "RIO: RapidIO init\n");
42
43 /* Platform specific initialization */
44 platform_rio_init();
45
46 /* Enumerate all registered ports */
47 rio_init_mports();
48
49 return 0;
50}
51
52subsys_initcall(ppc_rio_init);
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index 76f4476cab44..d8837911bbc6 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -82,6 +82,12 @@ config LUAN
82 help 82 help
83 This option enables support for the IBM PPC440SP evaluation board. 83 This option enables support for the IBM PPC440SP evaluation board.
84 84
85config YUCCA
86 bool "Yucca"
87 select WANT_EARLY_SERIAL
88 help
89 This option enables support for the AMCC PPC440SPe evaluation board.
90
85config OCOTEA 91config OCOTEA
86 bool "Ocotea" 92 bool "Ocotea"
87 select WANT_EARLY_SERIAL 93 select WANT_EARLY_SERIAL
@@ -124,9 +130,14 @@ config 440SP
124 depends on LUAN 130 depends on LUAN
125 default y 131 default y
126 132
133config 440SPE
134 bool
135 depends on YUCCA
136 default y
137
127config 440 138config 440
128 bool 139 bool
129 depends on 440GP || 440SP || 440EP 140 depends on 440GP || 440SP || 440SPE || 440EP
130 default y 141 default y
131 142
132config 440A 143config 440A
@@ -158,7 +169,7 @@ config BOOKE
158 169
159config IBM_OCP 170config IBM_OCP
160 bool 171 bool
161 depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT 172 depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || YUCCA || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
162 default y 173 default y
163 174
164config XILINX_OCP 175config XILINX_OCP
@@ -168,7 +179,7 @@ config XILINX_OCP
168 179
169config IBM_EMAC4 180config IBM_EMAC4
170 bool 181 bool
171 depends on 440GX || 440SP 182 depends on 440GX || 440SP || 440SPE
172 default y 183 default y
173 184
174config BIOS_FIXUP 185config BIOS_FIXUP
@@ -214,7 +225,7 @@ config EMBEDDEDBOOT
214 225
215config IBM_OPENBIOS 226config IBM_OPENBIOS
216 bool 227 bool
217 depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT 228 depends on ASH || REDWOOD_5 || REDWOOD_6
218 default y 229 default y
219 230
220config PPC4xx_DMA 231config PPC4xx_DMA
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
index 1dd6d7fd6a9a..c9bb61170954 100644
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_EBONY) += ebony.o
7obj-$(CONFIG_EP405) += ep405.o 7obj-$(CONFIG_EP405) += ep405.o
8obj-$(CONFIG_BUBINGA) += bubinga.o 8obj-$(CONFIG_BUBINGA) += bubinga.o
9obj-$(CONFIG_LUAN) += luan.o 9obj-$(CONFIG_LUAN) += luan.o
10obj-$(CONFIG_YUCCA) += yucca.o
10obj-$(CONFIG_OCOTEA) += ocotea.o 11obj-$(CONFIG_OCOTEA) += ocotea.o
11obj-$(CONFIG_REDWOOD_5) += redwood5.o 12obj-$(CONFIG_REDWOOD_5) += redwood5.o
12obj-$(CONFIG_REDWOOD_6) += redwood6.o 13obj-$(CONFIG_REDWOOD_6) += redwood6.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_440EP) += ibm440ep.o
22obj-$(CONFIG_440GP) += ibm440gp.o 23obj-$(CONFIG_440GP) += ibm440gp.o
23obj-$(CONFIG_440GX) += ibm440gx.o 24obj-$(CONFIG_440GX) += ibm440gx.o
24obj-$(CONFIG_440SP) += ibm440sp.o 25obj-$(CONFIG_440SP) += ibm440sp.o
26obj-$(CONFIG_440SPE) += ppc440spe.o
25obj-$(CONFIG_405EP) += ibm405ep.o 27obj-$(CONFIG_405EP) += ibm405ep.o
26obj-$(CONFIG_405GPR) += ibm405gpr.o 28obj-$(CONFIG_405GPR) += ibm405gpr.o
27obj-$(CONFIG_VIRTEX_II_PRO) += virtex-ii_pro.o 29obj-$(CONFIG_VIRTEX_II_PRO) += virtex-ii_pro.o
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c
index 3678abf86313..8110f55668c5 100644
--- a/arch/ppc/platforms/4xx/bubinga.c
+++ b/arch/ppc/platforms/4xx/bubinga.c
@@ -89,7 +89,7 @@ bubinga_early_serial_map(void)
89 * by 16. 89 * by 16.
90 */ 90 */
91 uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV); 91 uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV);
92 uart_clock = __res.bi_pllouta_freq / uart_div; 92 uart_clock = __res.bi_procfreq / uart_div;
93 93
94 /* Setup serial port access */ 94 /* Setup serial port access */
95 memset(&port, 0, sizeof(port)); 95 memset(&port, 0, sizeof(port));
diff --git a/arch/ppc/platforms/4xx/bubinga.h b/arch/ppc/platforms/4xx/bubinga.h
index b1df856f8e22..b5380cfaf5c0 100644
--- a/arch/ppc/platforms/4xx/bubinga.h
+++ b/arch/ppc/platforms/4xx/bubinga.h
@@ -1,52 +1,34 @@
1/* 1/*
2 * Support for IBM PPC 405EP evaluation board (Bubinga). 2 * arch/ppc/platforms/4xx/bubinga.h
3 * 3 *
4 * Author: SAW (IBM), derived from walnut.h. 4 * Bubinga board definitions
5 * Maintained by MontaVista Software <source@mvista.com> 5 *
6 * Copyright (c) 2005 DENX Software Engineering
7 * Stefan Roese <sr@denx.de>
8 *
9 * Based on original work by
10 * SAW (IBM)
11 * 2003 (c) MontaVista Softare Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
6 * 17 *
7 * 2003 (c) MontaVista Softare Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */ 18 */
12 19
13#ifdef __KERNEL__ 20#ifdef __KERNEL__
14#ifndef __BUBINGA_H__ 21#ifndef __BUBINGA_H__
15#define __BUBINGA_H__ 22#define __BUBINGA_H__
16 23
17/* 405EP */ 24#include <linux/config.h>
18#include <platforms/4xx/ibm405ep.h> 25#include <platforms/4xx/ibm405ep.h>
19 26#include <asm/ppcboot.h>
20#ifndef __ASSEMBLY__
21/*
22 * Data structure defining board information maintained by the boot
23 * ROM on IBM's evaluation board. An effort has been made to
24 * keep the field names consistent with the 8xx 'bd_t' board info
25 * structures.
26 */
27
28typedef struct board_info {
29 unsigned char bi_s_version[4]; /* Version of this structure */
30 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
31 unsigned int bi_memsize; /* DRAM installed, in bytes */
32 unsigned char bi_enetaddr[2][6]; /* Local Ethernet MAC address */ unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
33 unsigned int bi_intfreq; /* Processor speed, in Hz */
34 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
35 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
36 unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
37 unsigned int bi_pllouta_freq; /* PLL OUTA speed, in Hz */
38} bd_t;
39
40/* Some 4xx parts use a different timebase frequency from the internal clock.
41*/
42#define bi_tbfreq bi_intfreq
43
44 27
45/* Memory map for the Bubinga board. 28/* Memory map for the Bubinga board.
46 * Generic 4xx plus RTC. 29 * Generic 4xx plus RTC.
47 */ 30 */
48 31
49extern void *bubinga_rtc_base;
50#define BUBINGA_RTC_PADDR ((uint)0xf0000000) 32#define BUBINGA_RTC_PADDR ((uint)0xf0000000)
51#define BUBINGA_RTC_VADDR BUBINGA_RTC_PADDR 33#define BUBINGA_RTC_VADDR BUBINGA_RTC_PADDR
52#define BUBINGA_RTC_SIZE ((uint)8*1024) 34#define BUBINGA_RTC_SIZE ((uint)8*1024)
@@ -58,12 +40,18 @@ extern void *bubinga_rtc_base;
58 * for typical configurations at various CPU speeds. 40 * for typical configurations at various CPU speeds.
59 * The base baud is calculated as (FWDA / EXT UART DIV / 16) 41 * The base baud is calculated as (FWDA / EXT UART DIV / 16)
60 */ 42 */
61#define BASE_BAUD 0 43#define BASE_BAUD 0
62 44
63#define BUBINGA_FPGA_BASE 0xF0300000 45/* Flash */
46#define PPC40x_FPGA_BASE 0xF0300000
47#define PPC40x_FPGA_REG_OFFS 1 /* offset to flash map reg */
48#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
49#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
50#define PPC40x_FLASH_LOW 0xFFF00000
51#define PPC40x_FLASH_HIGH 0xFFF80000
52#define PPC40x_FLASH_SIZE 0x80000
64 53
65#define PPC4xx_MACHINE_NAME "IBM Bubinga" 54#define PPC4xx_MACHINE_NAME "IBM Bubinga"
66 55
67#endif /* !__ASSEMBLY__ */
68#endif /* __BUBINGA_H__ */ 56#endif /* __BUBINGA_H__ */
69#endif /* __KERNEL__ */ 57#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
index d08faa46a0ae..b91ad4272dfe 100644
--- a/arch/ppc/platforms/4xx/ebony.h
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -24,8 +24,8 @@
24#define PPC44x_EMAC0_MR0 0xE0000800 24#define PPC44x_EMAC0_MR0 0xE0000800
25 25
26/* Where to find the MAC info */ 26/* Where to find the MAC info */
27#define EBONY_OPENBIOS_MAC_BASE 0xfffffe0c 27#define OPENBIOS_MAC_BASE 0xfffffe0c
28#define EBONY_OPENBIOS_MAC_OFFSET 0x0c 28#define OPENBIOS_MAC_OFFSET 0x0c
29 29
30/* Default clock rates for Rev. B and Rev. C silicon */ 30/* Default clock rates for Rev. B and Rev. C silicon */
31#define EBONY_440GP_RB_SYSCLK 33000000 31#define EBONY_440GP_RB_SYSCLK 33000000
diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
new file mode 100644
index 000000000000..6139a0b3393e
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ppc440spe.c
@@ -0,0 +1,148 @@
1/*
2 * arch/ppc/platforms/4xx/ppc440spe.c
3 *
4 * PPC440SPe I/O descriptions
5 *
6 * Roland Dreier <rolandd@cisco.com>
7 * Copyright (c) 2005 Cisco Systems. All rights reserved.
8 *
9 * Matt Porter <mporter@kernel.crashing.org>
10 * Copyright 2002-2005 MontaVista Software Inc.
11 *
12 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
13 * Copyright (c) 2003, 2004 Zultys Technologies
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 */
21#include <linux/init.h>
22#include <linux/module.h>
23#include <platforms/4xx/ppc440spe.h>
24#include <asm/ocp.h>
25#include <asm/ppc4xx_pic.h>
26
27static struct ocp_func_emac_data ppc440spe_emac0_def = {
28 .rgmii_idx = -1, /* No RGMII */
29 .rgmii_mux = -1, /* No RGMII */
30 .zmii_idx = -1, /* No ZMII */
31 .zmii_mux = -1, /* No ZMII */
32 .mal_idx = 0, /* MAL device index */
33 .mal_rx_chan = 0, /* MAL rx channel number */
34 .mal_tx_chan = 0, /* MAL tx channel number */
35 .wol_irq = 61, /* WOL interrupt number */
36 .mdio_idx = -1, /* No shared MDIO */
37 .tah_idx = -1, /* No TAH */
38};
39OCP_SYSFS_EMAC_DATA()
40
41static struct ocp_func_mal_data ppc440spe_mal0_def = {
42 .num_tx_chans = 1, /* Number of TX channels */
43 .num_rx_chans = 1, /* Number of RX channels */
44 .txeob_irq = 38, /* TX End Of Buffer IRQ */
45 .rxeob_irq = 39, /* RX End Of Buffer IRQ */
46 .txde_irq = 34, /* TX Descriptor Error IRQ */
47 .rxde_irq = 35, /* RX Descriptor Error IRQ */
48 .serr_irq = 33, /* MAL System Error IRQ */
49 .dcr_base = DCRN_MAL_BASE /* MAL0_CFG DCR number */
50};
51OCP_SYSFS_MAL_DATA()
52
53static struct ocp_func_iic_data ppc440spe_iic0_def = {
54 .fast_mode = 0, /* Use standad mode (100Khz) */
55};
56
57static struct ocp_func_iic_data ppc440spe_iic1_def = {
58 .fast_mode = 0, /* Use standad mode (100Khz) */
59};
60OCP_SYSFS_IIC_DATA()
61
62struct ocp_def core_ocp[] = {
63 { .vendor = OCP_VENDOR_IBM,
64 .function = OCP_FUNC_16550,
65 .index = 0,
66 .paddr = PPC440SPE_UART0_ADDR,
67 .irq = UART0_INT,
68 .pm = IBM_CPM_UART0,
69 },
70 { .vendor = OCP_VENDOR_IBM,
71 .function = OCP_FUNC_16550,
72 .index = 1,
73 .paddr = PPC440SPE_UART1_ADDR,
74 .irq = UART1_INT,
75 .pm = IBM_CPM_UART1,
76 },
77 { .vendor = OCP_VENDOR_IBM,
78 .function = OCP_FUNC_16550,
79 .index = 2,
80 .paddr = PPC440SPE_UART2_ADDR,
81 .irq = UART2_INT,
82 .pm = IBM_CPM_UART2,
83 },
84 { .vendor = OCP_VENDOR_IBM,
85 .function = OCP_FUNC_IIC,
86 .index = 0,
87 .paddr = 0x00000004f0000400ULL,
88 .irq = 2,
89 .pm = IBM_CPM_IIC0,
90 .additions = &ppc440spe_iic0_def,
91 .show = &ocp_show_iic_data
92 },
93 { .vendor = OCP_VENDOR_IBM,
94 .function = OCP_FUNC_IIC,
95 .index = 1,
96 .paddr = 0x00000004f0000500ULL,
97 .irq = 3,
98 .pm = IBM_CPM_IIC1,
99 .additions = &ppc440spe_iic1_def,
100 .show = &ocp_show_iic_data
101 },
102 { .vendor = OCP_VENDOR_IBM,
103 .function = OCP_FUNC_GPIO,
104 .index = 0,
105 .paddr = 0x00000004f0000700ULL,
106 .irq = OCP_IRQ_NA,
107 .pm = IBM_CPM_GPIO0,
108 },
109 { .vendor = OCP_VENDOR_IBM,
110 .function = OCP_FUNC_MAL,
111 .paddr = OCP_PADDR_NA,
112 .irq = OCP_IRQ_NA,
113 .pm = OCP_CPM_NA,
114 .additions = &ppc440spe_mal0_def,
115 .show = &ocp_show_mal_data,
116 },
117 { .vendor = OCP_VENDOR_IBM,
118 .function = OCP_FUNC_EMAC,
119 .index = 0,
120 .paddr = 0x00000004f0000800ULL,
121 .irq = 60,
122 .pm = OCP_CPM_NA,
123 .additions = &ppc440spe_emac0_def,
124 .show = &ocp_show_emac_data,
125 },
126 { .vendor = OCP_VENDOR_INVALID
127 }
128};
129
130/* Polarity and triggering settings for internal interrupt sources */
131struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
132 { .polarity = 0xffffffff,
133 .triggering = 0x010f0004,
134 .ext_irq_mask = 0x00000000,
135 },
136 { .polarity = 0xffffffff,
137 .triggering = 0x001f8040,
138 .ext_irq_mask = 0x00007c30, /* IRQ6 - IRQ7, IRQ8 - IRQ12 */
139 },
140 { .polarity = 0xffffffff,
141 .triggering = 0x00000000,
142 .ext_irq_mask = 0x000000fc, /* IRQ0 - IRQ5 */
143 },
144 { .polarity = 0xffffffff,
145 .triggering = 0x00000000,
146 .ext_irq_mask = 0x00000000,
147 },
148};
diff --git a/arch/ppc/platforms/4xx/ppc440spe.h b/arch/ppc/platforms/4xx/ppc440spe.h
new file mode 100644
index 000000000000..2216846973b8
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ppc440spe.h
@@ -0,0 +1,66 @@
1/*
2 * arch/ppc/platforms/4xx/ibm440spe.h
3 *
4 * PPC440SPe definitions
5 *
6 * Roland Dreier <rolandd@cisco.com>
7 * Copyright (c) 2005 Cisco Systems. All rights reserved.
8 *
9 * Matt Porter <mporter@kernel.crashing.org>
10 * Copyright 2004-2005 MontaVista Software, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#ifdef __KERNEL__
19#ifndef __PPC_PLATFORMS_PPC440SPE_H
20#define __PPC_PLATFORMS_PPC440SPE_H
21
22#include <linux/config.h>
23
24#include <asm/ibm44x.h>
25
26/* UART */
27#define PPC440SPE_UART0_ADDR 0x00000004f0000200ULL
28#define PPC440SPE_UART1_ADDR 0x00000004f0000300ULL
29#define PPC440SPE_UART2_ADDR 0x00000004f0000600ULL
30#define UART0_INT 0
31#define UART1_INT 1
32#define UART2_INT 37
33
34/* Clock and Power Management */
35#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
36#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
37#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
38#define IBM_CPM_CPU 0x02000000 /* processor core */
39#define IBM_CPM_DMA 0x01000000 /* DMA controller */
40#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
41#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
42#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
43#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
44#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
45#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
46#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
47#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
48#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
49#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
50#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
51#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
52#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
53#define IBM_CPM_UART2 0x00000100 /* serial port 1 */
54#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
55#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
56#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */
57
58#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
59 | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
60 | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
61 | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
62 | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
63 | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
64 | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
65#endif /* __PPC_PLATFORMS_PPC440SP_H */
66#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
index d8019eec4704..281b4a2ffb96 100644
--- a/arch/ppc/platforms/4xx/sycamore.c
+++ b/arch/ppc/platforms/4xx/sycamore.c
@@ -88,9 +88,6 @@ ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
88void __init 88void __init
89sycamore_setup_arch(void) 89sycamore_setup_arch(void)
90{ 90{
91#define SYCAMORE_PS2_BASE 0xF0100000
92#define SYCAMORE_FPGA_BASE 0xF0300000
93
94 void *fpga_brdc; 91 void *fpga_brdc;
95 unsigned char fpga_brdc_data; 92 unsigned char fpga_brdc_data;
96 void *fpga_enable; 93 void *fpga_enable;
@@ -100,7 +97,7 @@ sycamore_setup_arch(void)
100 97
101 ppc4xx_setup_arch(); 98 ppc4xx_setup_arch();
102 99
103 ibm_ocp_set_emac(0, 1); 100 ibm_ocp_set_emac(0, 0);
104 101
105 kb_data = ioremap(SYCAMORE_PS2_BASE, 8); 102 kb_data = ioremap(SYCAMORE_PS2_BASE, 8);
106 if (!kb_data) { 103 if (!kb_data) {
@@ -111,7 +108,7 @@ sycamore_setup_arch(void)
111 108
112 kb_cs = kb_data + 1; 109 kb_cs = kb_data + 1;
113 110
114 fpga_status = ioremap(SYCAMORE_FPGA_BASE, 8); 111 fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
115 if (!fpga_status) { 112 if (!fpga_status) {
116 printk(KERN_CRIT 113 printk(KERN_CRIT
117 "sycamore_setup_arch() fpga_status ioremap failed\n"); 114 "sycamore_setup_arch() fpga_status ioremap failed\n");
diff --git a/arch/ppc/platforms/4xx/sycamore.h b/arch/ppc/platforms/4xx/sycamore.h
index 3e7b4e2c8c57..1cd6c824fd62 100644
--- a/arch/ppc/platforms/4xx/sycamore.h
+++ b/arch/ppc/platforms/4xx/sycamore.h
@@ -1,67 +1,52 @@
1/* 1/*
2 * arch/ppc/platforms/4xx/sycamore.h 2 * arch/ppc/platforms/4xx/sycamore.h
3 * 3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC 4 * Sycamore board definitions
5 * 405GPr "Sycamore" evaluation board.
6 * 5 *
7 * Author: Armin Kuster <akuster@mvista.com> 6 * Copyright (c) 2005 DENX Software Engineering
7 * Stefan Roese <sr@denx.de>
8 *
9 * Based on original work by
10 * Armin Kuster <akuster@mvista.com>
11 * 2000 (c) MontaVista, Software, Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
8 * 17 *
9 * 2000 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */ 18 */
14 19
15#ifdef __KERNEL__ 20#ifdef __KERNEL__
16#ifndef __ASM_SYCAMORE_H__ 21#ifndef __ASM_SYCAMORE_H__
17#define __ASM_SYCAMORE_H__ 22#define __ASM_SYCAMORE_H__
18 23
24#include <linux/config.h>
19#include <platforms/4xx/ibm405gpr.h> 25#include <platforms/4xx/ibm405gpr.h>
26#include <asm/ppcboot.h>
20 27
21#ifndef __ASSEMBLY__ 28/* Memory map for the IBM "Sycamore" 405GPr evaluation board.
22/*
23 * Data structure defining board information maintained by the boot
24 * ROM on IBM's "Sycamore" evaluation board. An effort has been made to
25 * keep the field names consistent with the 8xx 'bd_t' board info
26 * structures.
27 */
28
29typedef struct board_info {
30 unsigned char bi_s_version[4]; /* Version of this structure */
31 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
32 unsigned int bi_memsize; /* DRAM installed, in bytes */
33 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
34 unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
35 unsigned int bi_intfreq; /* Processor speed, in Hz */
36 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
37 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
38} bd_t;
39
40/* Some 4xx parts use a different timebase frequency from the internal clock.
41*/
42#define bi_tbfreq bi_intfreq
43
44
45/* Memory map for the IBM "Sycamore" 405GP evaluation board.
46 * Generic 4xx plus RTC. 29 * Generic 4xx plus RTC.
47 */ 30 */
48 31
49extern void *sycamore_rtc_base;
50#define SYCAMORE_RTC_PADDR ((uint)0xf0000000) 32#define SYCAMORE_RTC_PADDR ((uint)0xf0000000)
51#define SYCAMORE_RTC_VADDR SYCAMORE_RTC_PADDR 33#define SYCAMORE_RTC_VADDR SYCAMORE_RTC_PADDR
52#define SYCAMORE_RTC_SIZE ((uint)8*1024) 34#define SYCAMORE_RTC_SIZE ((uint)8*1024)
53 35
54#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
55#define BASE_BAUD 201600
56#else
57#define BASE_BAUD 691200 36#define BASE_BAUD 691200
58#endif
59 37
60#define SYCAMORE_PS2_BASE 0xF0100000 38#define SYCAMORE_PS2_BASE 0xF0100000
61#define SYCAMORE_FPGA_BASE 0xF0300000 39
40/* Flash */
41#define PPC40x_FPGA_BASE 0xF0300000
42#define PPC40x_FPGA_REG_OFFS 5 /* offset to flash map reg */
43#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
44#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
45#define PPC40x_FLASH_LOW 0xFFF00000
46#define PPC40x_FLASH_HIGH 0xFFF80000
47#define PPC40x_FLASH_SIZE 0x80000
62 48
63#define PPC4xx_MACHINE_NAME "IBM Sycamore" 49#define PPC4xx_MACHINE_NAME "IBM Sycamore"
64 50
65#endif /* !__ASSEMBLY__ */
66#endif /* __ASM_SYCAMORE_H__ */ 51#endif /* __ASM_SYCAMORE_H__ */
67#endif /* __KERNEL__ */ 52#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
index a33eda4b7489..74cb33182d9f 100644
--- a/arch/ppc/platforms/4xx/walnut.c
+++ b/arch/ppc/platforms/4xx/walnut.c
@@ -90,7 +90,7 @@ walnut_setup_arch(void)
90 90
91 kb_cs = kb_data + 1; 91 kb_cs = kb_data + 1;
92 92
93 fpga_status = ioremap(WALNUT_FPGA_BASE, 8); 93 fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
94 if (!fpga_status) { 94 if (!fpga_status) {
95 printk(KERN_CRIT 95 printk(KERN_CRIT
96 "walnut_setup_arch() fpga_status ioremap failed\n"); 96 "walnut_setup_arch() fpga_status ioremap failed\n");
diff --git a/arch/ppc/platforms/4xx/walnut.h b/arch/ppc/platforms/4xx/walnut.h
index 04cfbf3696b9..dcf2691698c0 100644
--- a/arch/ppc/platforms/4xx/walnut.h
+++ b/arch/ppc/platforms/4xx/walnut.h
@@ -1,72 +1,55 @@
1/* 1/*
2 * arch/ppc/platforms/4xx/walnut.h 2 * arch/ppc/platforms/4xx/walnut.h
3 * 3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC 4 * Walnut board definitions
5 * 405GP "Walnut" evaluation board.
6 * 5 *
7 * Authors: Grant Erickson <grant@lcse.umn.edu>, Frank Rowand 6 * Copyright (c) 2005 DENX Software Engineering
8 * <frank_rowand@mvista.com>, Debbie Chu <debbie_chu@mvista.com> or 7 * Stefan Roese <sr@denx.de>
9 * source@mvista.com
10 * 8 *
11 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> 9 * Based on original work by
10 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
11 * Frank Rowand <frank_rowand@mvista.com>
12 * Debbie Chu <debbie_chu@mvista.com>
13 * 2000 (c) MontaVista, Software, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
12 * 19 *
13 * 2000 (c) MontaVista, Software, Inc. This file is licensed under
14 * the terms of the GNU General Public License version 2. This program
15 * is licensed "as is" without any warranty of any kind, whether express
16 * or implied.
17 */ 20 */
18 21
19#ifdef __KERNEL__ 22#ifdef __KERNEL__
20#ifndef __ASM_WALNUT_H__ 23#ifndef __ASM_WALNUT_H__
21#define __ASM_WALNUT_H__ 24#define __ASM_WALNUT_H__
22 25
23/* We have a 405GP core */ 26#include <linux/config.h>
24#include <platforms/4xx/ibm405gp.h> 27#include <platforms/4xx/ibm405gp.h>
25 28#include <asm/ppcboot.h>
26#ifndef __ASSEMBLY__
27/*
28 * Data structure defining board information maintained by the boot
29 * ROM on IBM's "Walnut" evaluation board. An effort has been made to
30 * keep the field names consistent with the 8xx 'bd_t' board info
31 * structures.
32 */
33
34typedef struct board_info {
35 unsigned char bi_s_version[4]; /* Version of this structure */
36 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
37 unsigned int bi_memsize; /* DRAM installed, in bytes */
38 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
39 unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
40 unsigned int bi_intfreq; /* Processor speed, in Hz */
41 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
42 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
43} bd_t;
44
45/* Some 4xx parts use a different timebase frequency from the internal clock.
46*/
47#define bi_tbfreq bi_intfreq
48
49 29
50/* Memory map for the IBM "Walnut" 405GP evaluation board. 30/* Memory map for the IBM "Walnut" 405GP evaluation board.
51 * Generic 4xx plus RTC. 31 * Generic 4xx plus RTC.
52 */ 32 */
53 33
54extern void *walnut_rtc_base;
55#define WALNUT_RTC_PADDR ((uint)0xf0000000) 34#define WALNUT_RTC_PADDR ((uint)0xf0000000)
56#define WALNUT_RTC_VADDR WALNUT_RTC_PADDR 35#define WALNUT_RTC_VADDR WALNUT_RTC_PADDR
57#define WALNUT_RTC_SIZE ((uint)8*1024) 36#define WALNUT_RTC_SIZE ((uint)8*1024)
58 37
59#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
60#define BASE_BAUD 201600
61#else
62#define BASE_BAUD 691200 38#define BASE_BAUD 691200
63#endif
64 39
65#define WALNUT_PS2_BASE 0xF0100000 40#define WALNUT_PS2_BASE 0xF0100000
66#define WALNUT_FPGA_BASE 0xF0300000 41
42/* Flash */
43#define PPC40x_FPGA_BASE 0xF0300000
44#define PPC40x_FPGA_REG_OFFS 5 /* offset to flash map reg */
45#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
46#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
47#define PPC40x_FLASH_LOW 0xFFF00000
48#define PPC40x_FLASH_HIGH 0xFFF80000
49#define PPC40x_FLASH_SIZE 0x80000
50#define WALNUT_FPGA_BASE PPC40x_FPGA_BASE
67 51
68#define PPC4xx_MACHINE_NAME "IBM Walnut" 52#define PPC4xx_MACHINE_NAME "IBM Walnut"
69 53
70#endif /* !__ASSEMBLY__ */
71#endif /* __ASM_WALNUT_H__ */ 54#endif /* __ASM_WALNUT_H__ */
72#endif /* __KERNEL__ */ 55#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
new file mode 100644
index 000000000000..e60f4bd437ec
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -0,0 +1,395 @@
1/*
2 * arch/ppc/platforms/4xx/yucca.c
3 *
4 * Yucca board specific routines
5 *
6 * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter)
7 *
8 * Copyright 2004-2005 MontaVista Software Inc.
9 * Copyright (c) 2005 Cisco Systems. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/config.h>
18#include <linux/stddef.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/reboot.h>
23#include <linux/pci.h>
24#include <linux/kdev_t.h>
25#include <linux/types.h>
26#include <linux/major.h>
27#include <linux/blkdev.h>
28#include <linux/console.h>
29#include <linux/delay.h>
30#include <linux/ide.h>
31#include <linux/initrd.h>
32#include <linux/seq_file.h>
33#include <linux/root_dev.h>
34#include <linux/tty.h>
35#include <linux/serial.h>
36#include <linux/serial_core.h>
37
38#include <asm/system.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <asm/dma.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/ocp.h>
45#include <asm/pci-bridge.h>
46#include <asm/time.h>
47#include <asm/todc.h>
48#include <asm/bootinfo.h>
49#include <asm/ppc4xx_pic.h>
50#include <asm/ppcboot.h>
51
52#include <syslib/ibm44x_common.h>
53#include <syslib/ibm440gx_common.h>
54#include <syslib/ibm440sp_common.h>
55#include <syslib/ppc440spe_pcie.h>
56
57extern bd_t __res;
58
59static struct ibm44x_clocks clocks __initdata;
60
61static void __init
62yucca_calibrate_decr(void)
63{
64 unsigned int freq;
65
66 if (mfspr(SPRN_CCR1) & CCR1_TCS)
67 freq = YUCCA_TMR_CLK;
68 else
69 freq = clocks.cpu;
70
71 ibm44x_calibrate_decr(freq);
72}
73
74static int
75yucca_show_cpuinfo(struct seq_file *m)
76{
77 seq_printf(m, "vendor\t\t: AMCC\n");
78 seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n");
79
80 return 0;
81}
82
83static enum {
84 HOSE_UNKNOWN,
85 HOSE_PCIX,
86 HOSE_PCIE0,
87 HOSE_PCIE1,
88 HOSE_PCIE2
89} hose_type[4];
90
91static inline int
92yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
93{
94 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
95
96 if (hose_type[hose->index] == HOSE_PCIX) {
97 static char pci_irq_table[][4] =
98 /*
99 * PCI IDSEL/INTPIN->INTLINE
100 * A B C D
101 */
102 {
103 { 81, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */
104 };
105 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
106 return PCI_IRQ_TABLE_LOOKUP;
107 } else if (hose_type[hose->index] == HOSE_PCIE0) {
108 static char pci_irq_table[][4] =
109 /*
110 * PCI IDSEL/INTPIN->INTLINE
111 * A B C D
112 */
113 {
114 { 96, 97, 98, 99 },
115 };
116 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
117 return PCI_IRQ_TABLE_LOOKUP;
118 } else if (hose_type[hose->index] == HOSE_PCIE1) {
119 static char pci_irq_table[][4] =
120 /*
121 * PCI IDSEL/INTPIN->INTLINE
122 * A B C D
123 */
124 {
125 { 100, 101, 102, 103 },
126 };
127 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
128 return PCI_IRQ_TABLE_LOOKUP;
129 } else if (hose_type[hose->index] == HOSE_PCIE2) {
130 static char pci_irq_table[][4] =
131 /*
132 * PCI IDSEL/INTPIN->INTLINE
133 * A B C D
134 */
135 {
136 { 104, 105, 106, 107 },
137 };
138 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
139 return PCI_IRQ_TABLE_LOOKUP;
140 }
141 return -1;
142}
143
144static void __init yucca_set_emacdata(void)
145{
146 struct ocp_def *def;
147 struct ocp_func_emac_data *emacdata;
148
149 /* Set phy_map, phy_mode, and mac_addr for the EMAC */
150 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
151 emacdata = def->additions;
152 emacdata->phy_map = 0x00000001; /* Skip 0x00 */
153 emacdata->phy_mode = PHY_MODE_GMII;
154 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
155}
156
157static int __init yucca_pcie_card_present(int port)
158{
159 void __iomem *pcie_fpga_base;
160 u16 reg;
161
162 pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
163 reg = in_be16(pcie_fpga_base + FPGA_REG1C);
164 iounmap(pcie_fpga_base);
165
166 switch(port) {
167 case 0: return !(reg & FPGA_REG1C_PE0_PRSNT);
168 case 1: return !(reg & FPGA_REG1C_PE1_PRSNT);
169 case 2: return !(reg & FPGA_REG1C_PE2_PRSNT);
170 default: return 0;
171 }
172}
173
174/*
175 * For the given slot, set rootpoint mode, send power to the slot,
176 * turn on the green LED and turn off the yellow LED, enable the clock
177 * and turn off reset.
178 */
179static void __init yucca_setup_pcie_fpga_rootpoint(int port)
180{
181 void __iomem *pcie_reg_fpga_base;
182 u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
183
184 pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
185
186 switch(port) {
187 case 0:
188 rootpoint = FPGA_REG1C_PE0_ROOTPOINT;
189 endpoint = 0;
190 power = FPGA_REG1A_PE0_PWRON;
191 green_led = FPGA_REG1A_PE0_GLED;
192 clock = FPGA_REG1A_PE0_REFCLK_ENABLE;
193 yellow_led = FPGA_REG1A_PE0_YLED;
194 reset_off = FPGA_REG1C_PE0_PERST;
195 break;
196 case 1:
197 rootpoint = 0;
198 endpoint = FPGA_REG1C_PE1_ENDPOINT;
199 power = FPGA_REG1A_PE1_PWRON;
200 green_led = FPGA_REG1A_PE1_GLED;
201 clock = FPGA_REG1A_PE1_REFCLK_ENABLE;
202 yellow_led = FPGA_REG1A_PE1_YLED;
203 reset_off = FPGA_REG1C_PE1_PERST;
204 break;
205 case 2:
206 rootpoint = 0;
207 endpoint = FPGA_REG1C_PE2_ENDPOINT;
208 power = FPGA_REG1A_PE2_PWRON;
209 green_led = FPGA_REG1A_PE2_GLED;
210 clock = FPGA_REG1A_PE2_REFCLK_ENABLE;
211 yellow_led = FPGA_REG1A_PE2_YLED;
212 reset_off = FPGA_REG1C_PE2_PERST;
213 break;
214
215 default:
216 return;
217 }
218
219 out_be16(pcie_reg_fpga_base + FPGA_REG1A,
220 ~(power | clock | green_led) &
221 (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A)));
222 out_be16(pcie_reg_fpga_base + FPGA_REG1C,
223 ~(endpoint | reset_off) &
224 (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C)));
225
226 /*
227 * Leave device in reset for a while after powering on the
228 * slot to give it a chance to initialize.
229 */
230 mdelay(250);
231
232 out_be16(pcie_reg_fpga_base + FPGA_REG1C,
233 reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C));
234
235 iounmap(pcie_reg_fpga_base);
236}
237
238static void __init
239yucca_setup_hoses(void)
240{
241 struct pci_controller *hose;
242 char name[20];
243 int i;
244
245 if (0 && ppc440spe_init_pcie()) {
246 printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n");
247 return;
248 }
249
250 for (i = 0; i <= 2; ++i) {
251 if (!yucca_pcie_card_present(i))
252 continue;
253
254 printk(KERN_INFO "PCIE%d: card present\n", i);
255 yucca_setup_pcie_fpga_rootpoint(i);
256 if (ppc440spe_init_pcie_rootport(i)) {
257 printk(KERN_WARNING "PCIE%d: initialization failed\n", i);
258 continue;
259 }
260
261 hose = pcibios_alloc_controller();
262 if (!hose)
263 return;
264
265 sprintf(name, "PCIE%d host bridge", i);
266 pci_init_resource(&hose->io_resource,
267 YUCCA_PCIX_LOWER_IO,
268 YUCCA_PCIX_UPPER_IO,
269 IORESOURCE_IO,
270 name);
271
272 hose->mem_space.start = YUCCA_PCIE_LOWER_MEM +
273 i * YUCCA_PCIE_MEM_SIZE;
274 hose->mem_space.end = hose->mem_space.start +
275 YUCCA_PCIE_MEM_SIZE - 1;
276
277 pci_init_resource(&hose->mem_resources[0],
278 hose->mem_space.start,
279 hose->mem_space.end,
280 IORESOURCE_MEM,
281 name);
282
283 hose->first_busno = 0;
284 hose->last_busno = 15;
285 hose_type[hose->index] = HOSE_PCIE0 + i;
286
287 ppc440spe_setup_pcie(hose, i);
288 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
289 }
290
291 ppc_md.pci_swizzle = common_swizzle;
292 ppc_md.pci_map_irq = yucca_map_irq;
293}
294
295TODC_ALLOC();
296
297static void __init
298yucca_early_serial_map(void)
299{
300 struct uart_port port;
301
302 /* Setup ioremapped serial port access */
303 memset(&port, 0, sizeof(port));
304 port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8);
305 port.irq = UART0_INT;
306 port.uartclk = clocks.uart0;
307 port.regshift = 0;
308 port.iotype = SERIAL_IO_MEM;
309 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
310 port.line = 0;
311
312 if (early_serial_setup(&port) != 0) {
313 printk("Early serial init of port 0 failed\n");
314 }
315
316 port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8);
317 port.irq = UART1_INT;
318 port.uartclk = clocks.uart1;
319 port.line = 1;
320
321 if (early_serial_setup(&port) != 0) {
322 printk("Early serial init of port 1 failed\n");
323 }
324
325 port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8);
326 port.irq = UART2_INT;
327 port.uartclk = BASE_BAUD;
328 port.line = 2;
329
330 if (early_serial_setup(&port) != 0) {
331 printk("Early serial init of port 2 failed\n");
332 }
333}
334
335static void __init
336yucca_setup_arch(void)
337{
338 yucca_set_emacdata();
339
340#if !defined(CONFIG_BDI_SWITCH)
341 /*
342 * The Abatron BDI JTAG debugger does not tolerate others
343 * mucking with the debug registers.
344 */
345 mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
346#endif
347
348 /*
349 * Determine various clocks.
350 * To be completely correct we should get SysClk
351 * from FPGA, because it can be changed by on-board switches
352 * --ebs
353 */
354 /* 440GX and 440SPe clocking is the same - rd */
355 ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
356 ocp_sys_info.opb_bus_freq = clocks.opb;
357
358 /* init to some ~sane value until calibrate_delay() runs */
359 loops_per_jiffy = 50000000/HZ;
360
361 /* Setup PCIXn host bridges */
362 yucca_setup_hoses();
363
364#ifdef CONFIG_BLK_DEV_INITRD
365 if (initrd_start)
366 ROOT_DEV = Root_RAM0;
367 else
368#endif
369#ifdef CONFIG_ROOT_NFS
370 ROOT_DEV = Root_NFS;
371#else
372 ROOT_DEV = Root_HDA1;
373#endif
374
375 yucca_early_serial_map();
376
377 /* Identify the system */
378 printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n");
379}
380
381void __init platform_init(unsigned long r3, unsigned long r4,
382 unsigned long r5, unsigned long r6, unsigned long r7)
383{
384 ibm44x_platform_init(r3, r4, r5, r6, r7);
385
386 ppc_md.setup_arch = yucca_setup_arch;
387 ppc_md.show_cpuinfo = yucca_show_cpuinfo;
388 ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
389 ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
390
391 ppc_md.calibrate_decr = yucca_calibrate_decr;
392#ifdef CONFIG_KGDB
393 ppc_md.early_serial_map = yucca_early_serial_map;
394#endif
395}
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
new file mode 100644
index 000000000000..01a4afea1514
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -0,0 +1,111 @@
1/*
2 * arch/ppc/platforms/4xx/yucca.h
3 *
4 * Yucca board definitions
5 *
6 * Roland Dreier <rolandd@cisco.com> (based on luan.h by Matt Porter)
7 *
8 * Copyright 2004-2005 MontaVista Software Inc.
9 * Copyright (c) 2005 Cisco Systems. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#ifdef __KERNEL__
19#ifndef __ASM_YUCCA_H__
20#define __ASM_YUCCA_H__
21
22#include <linux/config.h>
23#include <platforms/4xx/ppc440spe.h>
24
25/* F/W TLB mapping used in bootloader glue to reset EMAC */
26#define PPC44x_EMAC0_MR0 0xa0000800
27
28/* Location of MAC addresses in PIBS image */
29#define PIBS_FLASH_BASE 0xffe00000
30#define PIBS_MAC_BASE (PIBS_FLASH_BASE+0x1b0400)
31
32/* External timer clock frequency */
33#define YUCCA_TMR_CLK 25000000
34
35/*
36 * FPGA registers
37 */
38#define YUCCA_FPGA_REG_BASE 0x00000004e2000000ULL
39#define YUCCA_FPGA_REG_SIZE 0x24
40
41#define FPGA_REG1A 0x1a
42
43#define FPGA_REG1A_PE0_GLED 0x8000
44#define FPGA_REG1A_PE1_GLED 0x4000
45#define FPGA_REG1A_PE2_GLED 0x2000
46#define FPGA_REG1A_PE0_YLED 0x1000
47#define FPGA_REG1A_PE1_YLED 0x0800
48#define FPGA_REG1A_PE2_YLED 0x0400
49#define FPGA_REG1A_PE0_PWRON 0x0200
50#define FPGA_REG1A_PE1_PWRON 0x0100
51#define FPGA_REG1A_PE2_PWRON 0x0080
52#define FPGA_REG1A_PE0_REFCLK_ENABLE 0x0040
53#define FPGA_REG1A_PE1_REFCLK_ENABLE 0x0020
54#define FPGA_REG1A_PE2_REFCLK_ENABLE 0x0010
55#define FPGA_REG1A_PE_SPREAD0 0x0008
56#define FPGA_REG1A_PE_SPREAD1 0x0004
57#define FPGA_REG1A_PE_SELSOURCE_0 0x0002
58#define FPGA_REG1A_PE_SELSOURCE_1 0x0001
59
60#define FPGA_REG1C 0x1c
61
62#define FPGA_REG1C_PE0_ROOTPOINT 0x8000
63#define FPGA_REG1C_PE1_ENDPOINT 0x4000
64#define FPGA_REG1C_PE2_ENDPOINT 0x2000
65#define FPGA_REG1C_PE0_PRSNT 0x1000
66#define FPGA_REG1C_PE1_PRSNT 0x0800
67#define FPGA_REG1C_PE2_PRSNT 0x0400
68#define FPGA_REG1C_PE0_WAKE 0x0080
69#define FPGA_REG1C_PE1_WAKE 0x0040
70#define FPGA_REG1C_PE2_WAKE 0x0020
71#define FPGA_REG1C_PE0_PERST 0x0010
72#define FPGA_REG1C_PE1_PERST 0x0008
73#define FPGA_REG1C_PE2_PERST 0x0004
74
75/*
76 * Serial port defines
77 */
78#define RS_TABLE_SIZE 3
79
80/* PIBS defined UART mappings, used before early_serial_setup */
81#define UART0_IO_BASE 0xa0000200
82#define UART1_IO_BASE 0xa0000300
83#define UART2_IO_BASE 0xa0000600
84
85#define BASE_BAUD 11059200
86#define STD_UART_OP(num) \
87 { 0, BASE_BAUD, 0, UART##num##_INT, \
88 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
89 iomem_base: (void*)UART##num##_IO_BASE, \
90 io_type: SERIAL_IO_MEM},
91
92#define SERIAL_PORT_DFNS \
93 STD_UART_OP(0) \
94 STD_UART_OP(1) \
95 STD_UART_OP(2)
96
97/* PCI support */
98#define YUCCA_PCIX_LOWER_IO 0x00000000
99#define YUCCA_PCIX_UPPER_IO 0x0000ffff
100#define YUCCA_PCIX_LOWER_MEM 0x80000000
101#define YUCCA_PCIX_UPPER_MEM 0x8fffffff
102#define YUCCA_PCIE_LOWER_MEM 0x90000000
103#define YUCCA_PCIE_MEM_SIZE 0x10000000
104
105#define YUCCA_PCIX_MEM_SIZE 0x10000000
106#define YUCCA_PCIX_MEM_OFFSET 0x00000000
107#define YUCCA_PCIE_MEM_SIZE 0x10000000
108#define YUCCA_PCIE_MEM_OFFSET 0x00000000
109
110#endif /* __ASM_YUCCA_H__ */
111#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index bd3ac0136756..16ad092d8a06 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -45,6 +45,8 @@
45 45
46#include <mm/mmu_decl.h> 46#include <mm/mmu_decl.h>
47 47
48#include <syslib/ppc85xx_rio.h>
49
48#include <platforms/85xx/mpc85xx_ads_common.h> 50#include <platforms/85xx/mpc85xx_ads_common.h>
49 51
50#ifndef CONFIG_PCI 52#ifndef CONFIG_PCI
@@ -189,3 +191,11 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
189} 191}
190 192
191#endif /* CONFIG_PCI */ 193#endif /* CONFIG_PCI */
194
195#ifdef CONFIG_RAPIDIO
196void platform_rio_init(void)
197{
198 /* 512MB RIO LAW at 0xc0000000 */
199 mpc85xx_rio_setup(0xc0000000, 0x20000000);
200}
201#endif /* CONFIG_RAPIDIO */
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 1e1b85f8193a..15ce9d070634 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -37,6 +37,7 @@
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/fsl_devices.h> 38#include <linux/fsl_devices.h>
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/rio.h>
40 41
41#include <asm/system.h> 42#include <asm/system.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
@@ -57,6 +58,7 @@
57 58
58#include <syslib/cpm2_pic.h> 59#include <syslib/cpm2_pic.h>
59#include <syslib/ppc85xx_common.h> 60#include <syslib/ppc85xx_common.h>
61#include <syslib/ppc85xx_rio.h>
60 62
61 63
62unsigned char __res[sizeof(bd_t)]; 64unsigned char __res[sizeof(bd_t)];
@@ -273,6 +275,18 @@ int mpc85xx_exclude_device(u_char bus, u_char devfn)
273} 275}
274#endif /* CONFIG_PCI */ 276#endif /* CONFIG_PCI */
275 277
278#ifdef CONFIG_RAPIDIO
279void
280platform_rio_init(void)
281{
282 /*
283 * The STx firmware configures the RapidIO Local Access Window
284 * at 0xc0000000 with a size of 512MB.
285 */
286 mpc85xx_rio_setup(0xc0000000, 0x20000000);
287}
288#endif /* CONFIG_RAPIDIO */
289
276void __init 290void __init
277platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 291platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
278 unsigned long r6, unsigned long r7) 292 unsigned long r6, unsigned long r7)
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index b1324564456e..b9d844f88c2b 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -52,6 +52,8 @@ static u32 ev64360_bus_frequency;
52 52
53unsigned char __res[sizeof(bd_t)]; 53unsigned char __res[sizeof(bd_t)];
54 54
55TODC_ALLOC();
56
55static int __init 57static int __init
56ev64360_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) 58ev64360_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
57{ 59{
@@ -182,6 +184,9 @@ ev64360_setup_peripherals(void)
182 EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE, 0); 184 EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE, 0);
183 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); 185 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
184 186
187 TODC_INIT(TODC_TYPE_DS1501, 0, 0,
188 ioremap(EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE), 8);
189
185 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN, 190 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
186 EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0); 191 EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
187 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN); 192 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
@@ -496,6 +501,13 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
496 ppc_md.power_off = ev64360_power_off; 501 ppc_md.power_off = ev64360_power_off;
497 ppc_md.halt = ev64360_halt; 502 ppc_md.halt = ev64360_halt;
498 ppc_md.find_end_of_memory = ev64360_find_end_of_memory; 503 ppc_md.find_end_of_memory = ev64360_find_end_of_memory;
504 ppc_md.init = NULL;
505
506 ppc_md.time_init = todc_time_init;
507 ppc_md.set_rtc_time = todc_set_rtc_time;
508 ppc_md.get_rtc_time = todc_get_rtc_time;
509 ppc_md.nvram_read_val = todc_direct_read_val;
510 ppc_md.nvram_write_val = todc_direct_write_val;
499 ppc_md.calibrate_decr = ev64360_calibrate_decr; 511 ppc_md.calibrate_decr = ev64360_calibrate_decr;
500 512
501#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) 513#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index b4ef15b45c4a..5bd33baac243 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_440EP) += ibm440gx_common.o
15obj-$(CONFIG_440GP) += ibm440gp_common.o 15obj-$(CONFIG_440GP) += ibm440gp_common.o
16obj-$(CONFIG_440GX) += ibm440gx_common.o 16obj-$(CONFIG_440GX) += ibm440gx_common.o
17obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o 17obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o
18obj-$(CONFIG_440SPE) += ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o
18ifeq ($(CONFIG_4xx),y) 19ifeq ($(CONFIG_4xx),y)
19ifeq ($(CONFIG_VIRTEX_II_PRO),y) 20ifeq ($(CONFIG_VIRTEX_II_PRO),y)
20obj-$(CONFIG_40x) += xilinx_pic.o 21obj-$(CONFIG_40x) += xilinx_pic.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
32obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o 33obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
33ifeq ($(CONFIG_40x),y) 34ifeq ($(CONFIG_40x),y)
34obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o 35obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o
36obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
35endif 37endif
36endif 38endif
37obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ 39obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
@@ -46,12 +48,14 @@ obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
46obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o 48obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
47obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o 49obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o
48obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o 50obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o
51obj-$(CONFIG_EV64360) += todc_time.o
49obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o 52obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o
50obj-$(CONFIG_GEMINI) += open_pic.o 53obj-$(CONFIG_GEMINI) += open_pic.o
51obj-$(CONFIG_GT64260) += gt64260_pic.o 54obj-$(CONFIG_GT64260) += gt64260_pic.o
52obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o 55obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o
53obj-$(CONFIG_HDPU) += pci_auto.o 56obj-$(CONFIG_HDPU) += pci_auto.o
54obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o 57obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o
58obj-$(CONFIG_YUCCA) += pci_auto.o todc_time.o
55obj-$(CONFIG_KATANA) += pci_auto.o 59obj-$(CONFIG_KATANA) += pci_auto.o
56obj-$(CONFIG_MV64360) += mv64360_pic.o 60obj-$(CONFIG_MV64360) += mv64360_pic.o
57obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o 61obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o
diff --git a/arch/ppc/syslib/ibm440sp_common.c b/arch/ppc/syslib/ibm440sp_common.c
index 417d4cff77a0..cdafda127d81 100644
--- a/arch/ppc/syslib/ibm440sp_common.c
+++ b/arch/ppc/syslib/ibm440sp_common.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/ppc/syslib/ibm440sp_common.c 2 * arch/ppc/syslib/ibm440sp_common.c
3 * 3 *
4 * PPC440SP system library 4 * PPC440SP/PPC440SPe system library
5 * 5 *
6 * Matt Porter <mporter@kernel.crashing.org> 6 * Matt Porter <mporter@kernel.crashing.org>
7 * Copyright 2002-2005 MontaVista Software Inc. 7 * Copyright 2002-2005 MontaVista Software Inc.
@@ -35,7 +35,7 @@ unsigned long __init ibm440sp_find_end_of_memory(void)
35 u32 mem_size = 0; 35 u32 mem_size = 0;
36 36
37 /* Read two bank sizes and sum */ 37 /* Read two bank sizes and sum */
38 for (i=0; i<2; i++) 38 for (i=0; i< MQ0_NUM_BANKS; i++)
39 switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) { 39 switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) {
40 case MQ0_CONFIG_SIZE_8M: 40 case MQ0_CONFIG_SIZE_8M:
41 mem_size += PPC44x_MEM_SIZE_8M; 41 mem_size += PPC44x_MEM_SIZE_8M;
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
index 5152c8e41340..71db11d22158 100644
--- a/arch/ppc/syslib/ibm44x_common.c
+++ b/arch/ppc/syslib/ibm44x_common.c
@@ -20,6 +20,7 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/serial.h> 21#include <linux/serial.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/initrd.h>
23 24
24#include <asm/ibm44x.h> 25#include <asm/ibm44x.h>
25#include <asm/mmu.h> 26#include <asm/mmu.h>
@@ -214,9 +215,20 @@ void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned lo
214/* Called from machine_check_exception */ 215/* Called from machine_check_exception */
215void platform_machine_check(struct pt_regs *regs) 216void platform_machine_check(struct pt_regs *regs)
216{ 217{
218#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
219 printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x%08x\n",
220 mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
221 mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESRH),
222 mfdcr(DCRN_PLB0_BESRL));
223 printk("PLB1: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x%08x\n",
224 mfdcr(DCRN_PLB1_BEARH), mfdcr(DCRN_PLB1_BEARL),
225 mfdcr(DCRN_PLB1_ACR), mfdcr(DCRN_PLB1_BESRH),
226 mfdcr(DCRN_PLB1_BESRL));
227#else
217 printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x\n", 228 printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x\n",
218 mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL), 229 mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
219 mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESR)); 230 mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESR));
231#endif
220 printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n", 232 printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n",
221 mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL), 233 mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL),
222 mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1)); 234 mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1));
diff --git a/arch/ppc/syslib/ppc405_pci.c b/arch/ppc/syslib/ppc405_pci.c
index 81c83bf98df4..d6d838b16dac 100644
--- a/arch/ppc/syslib/ppc405_pci.c
+++ b/arch/ppc/syslib/ppc405_pci.c
@@ -89,13 +89,6 @@ ppc4xx_find_bridges(void)
89 isa_mem_base = 0; 89 isa_mem_base = 0;
90 pci_dram_offset = 0; 90 pci_dram_offset = 0;
91 91
92#if (PSR_PCI_ARBIT_EN > 1)
93 /* Check if running in slave mode */
94 if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) {
95 printk("Running as PCI slave, kernel PCI disabled !\n");
96 return;
97 }
98#endif
99 /* Setup PCI32 hose */ 92 /* Setup PCI32 hose */
100 hose_a = pcibios_alloc_controller(); 93 hose_a = pcibios_alloc_controller();
101 if (!hose_a) 94 if (!hose_a)
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
new file mode 100644
index 000000000000..1509fc1ddfb6
--- /dev/null
+++ b/arch/ppc/syslib/ppc440spe_pcie.c
@@ -0,0 +1,442 @@
1/*
2 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * Roland Dreier <rolandd@cisco.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/pci.h>
15#include <linux/init.h>
16
17#include <asm/reg.h>
18#include <asm/io.h>
19#include <asm/ibm44x.h>
20
21#include "ppc440spe_pcie.h"
22
23static int
24pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
25 int len, u32 *val)
26{
27 struct pci_controller *hose = bus->sysdata;
28
29 if (PCI_SLOT(devfn) != 1)
30 return PCIBIOS_DEVICE_NOT_FOUND;
31
32 offset += devfn << 12;
33
34 /*
35 * Note: the caller has already checked that offset is
36 * suitably aligned and that len is 1, 2 or 4.
37 */
38 switch (len) {
39 case 1:
40 *val = in_8(hose->cfg_data + offset);
41 break;
42 case 2:
43 *val = in_le16(hose->cfg_data + offset);
44 break;
45 default:
46 *val = in_le32(hose->cfg_data + offset);
47 break;
48 }
49
50 if (0) printk("%s: read %x(%d) @ %x\n", __func__, *val, len, offset);
51
52 return PCIBIOS_SUCCESSFUL;
53}
54
55static int
56pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
57 int len, u32 val)
58{
59 struct pci_controller *hose = bus->sysdata;
60
61 if (PCI_SLOT(devfn) != 1)
62 return PCIBIOS_DEVICE_NOT_FOUND;
63
64 offset += devfn << 12;
65
66 switch (len) {
67 case 1:
68 out_8(hose->cfg_data + offset, val);
69 break;
70 case 2:
71 out_le16(hose->cfg_data + offset, val);
72 break;
73 default:
74 out_le32(hose->cfg_data + offset, val);
75 break;
76 }
77 return PCIBIOS_SUCCESSFUL;
78}
79
80static struct pci_ops pcie_pci_ops =
81{
82 .read = pcie_read_config,
83 .write = pcie_write_config
84};
85
86enum {
87 PTYPE_ENDPOINT = 0x0,
88 PTYPE_LEGACY_ENDPOINT = 0x1,
89 PTYPE_ROOT_PORT = 0x4,
90
91 LNKW_X1 = 0x1,
92 LNKW_X4 = 0x4,
93 LNKW_X8 = 0x8
94};
95
96static void check_error(void)
97{
98 u32 valPE0, valPE1, valPE2;
99
100 /* SDR0_PEGPLLLCT1 reset */
101 if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
102 printk(KERN_INFO "PCIE: SDR0_PEGPLLLCT1 reset error 0x%8x\n", valPE0);
103 }
104
105 valPE0 = SDR_READ(PESDR0_RCSSET);
106 valPE1 = SDR_READ(PESDR1_RCSSET);
107 valPE2 = SDR_READ(PESDR2_RCSSET);
108
109 /* SDR0_PExRCSSET rstgu */
110 if ( !(valPE0 & 0x01000000) ||
111 !(valPE1 & 0x01000000) ||
112 !(valPE2 & 0x01000000)) {
113 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n");
114 }
115
116 /* SDR0_PExRCSSET rstdl */
117 if ( !(valPE0 & 0x00010000) ||
118 !(valPE1 & 0x00010000) ||
119 !(valPE2 & 0x00010000)) {
120 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n");
121 }
122
123 /* SDR0_PExRCSSET rstpyn */
124 if ( (valPE0 & 0x00001000) ||
125 (valPE1 & 0x00001000) ||
126 (valPE2 & 0x00001000)) {
127 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n");
128 }
129
130 /* SDR0_PExRCSSET hldplb */
131 if ( (valPE0 & 0x10000000) ||
132 (valPE1 & 0x10000000) ||
133 (valPE2 & 0x10000000)) {
134 printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n");
135 }
136
137 /* SDR0_PExRCSSET rdy */
138 if ( (valPE0 & 0x00100000) ||
139 (valPE1 & 0x00100000) ||
140 (valPE2 & 0x00100000)) {
141 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n");
142 }
143
144 /* SDR0_PExRCSSET shutdown */
145 if ( (valPE0 & 0x00000100) ||
146 (valPE1 & 0x00000100) ||
147 (valPE2 & 0x00000100)) {
148 printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n");
149 }
150}
151
152/*
153 * Initialize PCI Express core as described in User Manual section 27.12.1
154 */
155int ppc440spe_init_pcie(void)
156{
157 /* Set PLL clock receiver to LVPECL */
158 SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
159
160 check_error();
161
162 printk(KERN_INFO "PCIE initialization OK\n");
163
164 if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
165 printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
166 SDR_READ(PESDR0_PLLLCT2));
167
168 /* De-assert reset of PCIe PLL, wait for lock */
169 SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
170 udelay(3);
171
172 return 0;
173}
174
175int ppc440spe_init_pcie_rootport(int port)
176{
177 static int core_init;
178 void __iomem *utl_base;
179 u32 val = 0;
180 int i;
181
182 if (!core_init) {
183 ++core_init;
184 i = ppc440spe_init_pcie();
185 if (i)
186 return i;
187 }
188
189 /*
190 * Initialize various parts of the PCI Express core for our port:
191 *
192 * - Set as a root port and enable max width
193 * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
194 * - Set up UTL configuration.
195 * - Increase SERDES drive strength to levels suggested by AMCC.
196 * - De-assert RSTPYN, RSTDL and RSTGU.
197 */
198 switch (port) {
199 case 0:
200 SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
201
202 SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
203 SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
204
205 SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
206 SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
207 SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
208 SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
209 SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
210 SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
211 SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
212 SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
213
214 SDR_WRITE(PESDR0_RCSSET,
215 (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
216 break;
217
218 case 1:
219 SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
220
221 SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
222 SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
223
224 SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
225 SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
226 SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
227 SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
228
229 SDR_WRITE(PESDR1_RCSSET,
230 (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
231 break;
232
233 case 2:
234 SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
235
236 SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
237 SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
238
239 SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
240 SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
241 SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
242 SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
243
244 SDR_WRITE(PESDR2_RCSSET,
245 (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
246 break;
247 }
248
249 mdelay(1000);
250
251 switch (port) {
252 case 0: val = SDR_READ(PESDR0_RCSSTS); break;
253 case 1: val = SDR_READ(PESDR1_RCSSTS); break;
254 case 2: val = SDR_READ(PESDR2_RCSSTS); break;
255 }
256
257 if (!(val & (1 << 20)))
258 printk(KERN_INFO "PCIE%d: PGRST inactive\n", port);
259 else
260 printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val);
261
262 switch (port) {
263 case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break;
264 case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break;
265 case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break;
266 }
267
268 /*
269 * Map UTL registers at 0xc_1000_0n00
270 */
271 switch (port) {
272 case 0:
273 mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
274 mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000);
275 mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
276 mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
277 break;
278
279 case 1:
280 mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
281 mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000);
282 mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
283 mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
284 break;
285
286 case 2:
287 mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
288 mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000);
289 mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
290 mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
291 }
292
293 utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100);
294
295 /*
296 * Set buffer allocations and then assert VRB and TXE.
297 */
298 out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
299 out_be32(utl_base + PEUTL_INTR, 0x02000000);
300 out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
301 out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
302 out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
303 out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
304 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
305 out_be32(utl_base + PEUTL_PCTL, 0x80800066);
306
307 iounmap(utl_base);
308
309 /*
310 * We map PCI Express configuration access into the 512MB regions
311 * PCIE0: 0xc_4000_0000
312 * PCIE1: 0xc_8000_0000
313 * PCIE2: 0xc_c000_0000
314 */
315 switch (port) {
316 case 0:
317 mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
318 mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
319 mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
320 break;
321
322 case 1:
323 mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
324 mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
325 mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
326 break;
327
328 case 2:
329 mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
330 mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
331 mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
332 break;
333 }
334
335 /*
336 * Check for VC0 active and assert RDY.
337 */
338 switch (port) {
339 case 0:
340 if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16)))
341 printk(KERN_WARNING "PCIE0: VC0 not active\n");
342 SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
343 break;
344 case 1:
345 if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16)))
346 printk(KERN_WARNING "PCIE0: VC0 not active\n");
347 SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
348 break;
349 case 2:
350 if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16)))
351 printk(KERN_WARNING "PCIE0: VC0 not active\n");
352 SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
353 break;
354 }
355
356#if 0
357 /* Dump all config regs */
358 for (i = 0x300; i <= 0x320; ++i)
359 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
360 for (i = 0x340; i <= 0x353; ++i)
361 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
362 for (i = 0x370; i <= 0x383; ++i)
363 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
364 for (i = 0x3a0; i <= 0x3a2; ++i)
365 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
366 for (i = 0x3c0; i <= 0x3c3; ++i)
367 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
368#endif
369
370 mdelay(100);
371
372 return 0;
373}
374
375void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
376{
377 void __iomem *mbase;
378
379 /*
380 * Map 16MB, which is enough for 4 bits of bus #
381 */
382 hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000,
383 1 << 24);
384 hose->ops = &pcie_pci_ops;
385
386 /*
387 * Set bus numbers on our root port
388 */
389 mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096);
390 out_8(mbase + PCI_PRIMARY_BUS, 0);
391 out_8(mbase + PCI_SECONDARY_BUS, 0);
392
393 /*
394 * Set up outbound translation to hose->mem_space from PLB
395 * addresses at an offset of 0xd_0000_0000. We set the low
396 * bits of the mask to 11 to turn off splitting into 8
397 * subregions and to enable the outbound translation.
398 */
399 out_le32(mbase + PECFG_POM0LAH, 0);
400 out_le32(mbase + PECFG_POM0LAL, hose->mem_space.start);
401
402 switch (port) {
403 case 0:
404 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
405 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), hose->mem_space.start);
406 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
407 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
408 ~(hose->mem_space.end - hose->mem_space.start) | 3);
409 break;
410 case 1:
411 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
412 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), hose->mem_space.start);
413 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
414 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
415 ~(hose->mem_space.end - hose->mem_space.start) | 3);
416
417 break;
418 case 2:
419 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
420 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), hose->mem_space.start);
421 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
422 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
423 ~(hose->mem_space.end - hose->mem_space.start) | 3);
424 break;
425 }
426
427 /* Set up 16GB inbound memory window at 0 */
428 out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
429 out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
430 out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
431 out_le32(mbase + PECFG_BAR0LMPA, 0);
432 out_le32(mbase + PECFG_PIM0LAL, 0);
433 out_le32(mbase + PECFG_PIM0LAH, 0);
434 out_le32(mbase + PECFG_PIMEN, 0x1);
435
436 /* Enable I/O, Mem, and Busmaster cycles */
437 out_le16(mbase + PCI_COMMAND,
438 in_le16(mbase + PCI_COMMAND) |
439 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
440
441 iounmap(mbase);
442}
diff --git a/arch/ppc/syslib/ppc440spe_pcie.h b/arch/ppc/syslib/ppc440spe_pcie.h
new file mode 100644
index 000000000000..55b765ad3272
--- /dev/null
+++ b/arch/ppc/syslib/ppc440spe_pcie.h
@@ -0,0 +1,149 @@
1/*
2 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * Roland Dreier <rolandd@cisco.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __PPC_SYSLIB_PPC440SPE_PCIE_H
12#define __PPC_SYSLIB_PPC440SPE_PCIE_H
13
14#define DCRN_SDR0_CFGADDR 0x00e
15#define DCRN_SDR0_CFGDATA 0x00f
16
17#define DCRN_PCIE0_BASE 0x100
18#define DCRN_PCIE1_BASE 0x120
19#define DCRN_PCIE2_BASE 0x140
20#define PCIE0 DCRN_PCIE0_BASE
21#define PCIE1 DCRN_PCIE1_BASE
22#define PCIE2 DCRN_PCIE2_BASE
23
24#define DCRN_PEGPL_CFGBAH(base) (base + 0x00)
25#define DCRN_PEGPL_CFGBAL(base) (base + 0x01)
26#define DCRN_PEGPL_CFGMSK(base) (base + 0x02)
27#define DCRN_PEGPL_MSGBAH(base) (base + 0x03)
28#define DCRN_PEGPL_MSGBAL(base) (base + 0x04)
29#define DCRN_PEGPL_MSGMSK(base) (base + 0x05)
30#define DCRN_PEGPL_OMR1BAH(base) (base + 0x06)
31#define DCRN_PEGPL_OMR1BAL(base) (base + 0x07)
32#define DCRN_PEGPL_OMR1MSKH(base) (base + 0x08)
33#define DCRN_PEGPL_OMR1MSKL(base) (base + 0x09)
34#define DCRN_PEGPL_REGBAH(base) (base + 0x12)
35#define DCRN_PEGPL_REGBAL(base) (base + 0x13)
36#define DCRN_PEGPL_REGMSK(base) (base + 0x14)
37#define DCRN_PEGPL_SPECIAL(base) (base + 0x15)
38
39/*
40 * System DCRs (SDRs)
41 */
42#define PESDR0_PLLLCT1 0x03a0
43#define PESDR0_PLLLCT2 0x03a1
44#define PESDR0_PLLLCT3 0x03a2
45
46#define PESDR0_UTLSET1 0x0300
47#define PESDR0_UTLSET2 0x0301
48#define PESDR0_DLPSET 0x0302
49#define PESDR0_LOOP 0x0303
50#define PESDR0_RCSSET 0x0304
51#define PESDR0_RCSSTS 0x0305
52#define PESDR0_HSSL0SET1 0x0306
53#define PESDR0_HSSL0SET2 0x0307
54#define PESDR0_HSSL0STS 0x0308
55#define PESDR0_HSSL1SET1 0x0309
56#define PESDR0_HSSL1SET2 0x030a
57#define PESDR0_HSSL1STS 0x030b
58#define PESDR0_HSSL2SET1 0x030c
59#define PESDR0_HSSL2SET2 0x030d
60#define PESDR0_HSSL2STS 0x030e
61#define PESDR0_HSSL3SET1 0x030f
62#define PESDR0_HSSL3SET2 0x0310
63#define PESDR0_HSSL3STS 0x0311
64#define PESDR0_HSSL4SET1 0x0312
65#define PESDR0_HSSL4SET2 0x0313
66#define PESDR0_HSSL4STS 0x0314
67#define PESDR0_HSSL5SET1 0x0315
68#define PESDR0_HSSL5SET2 0x0316
69#define PESDR0_HSSL5STS 0x0317
70#define PESDR0_HSSL6SET1 0x0318
71#define PESDR0_HSSL6SET2 0x0319
72#define PESDR0_HSSL6STS 0x031a
73#define PESDR0_HSSL7SET1 0x031b
74#define PESDR0_HSSL7SET2 0x031c
75#define PESDR0_HSSL7STS 0x031d
76#define PESDR0_HSSCTLSET 0x031e
77#define PESDR0_LANE_ABCD 0x031f
78#define PESDR0_LANE_EFGH 0x0320
79
80#define PESDR1_UTLSET1 0x0340
81#define PESDR1_UTLSET2 0x0341
82#define PESDR1_DLPSET 0x0342
83#define PESDR1_LOOP 0x0343
84#define PESDR1_RCSSET 0x0344
85#define PESDR1_RCSSTS 0x0345
86#define PESDR1_HSSL0SET1 0x0346
87#define PESDR1_HSSL0SET2 0x0347
88#define PESDR1_HSSL0STS 0x0348
89#define PESDR1_HSSL1SET1 0x0349
90#define PESDR1_HSSL1SET2 0x034a
91#define PESDR1_HSSL1STS 0x034b
92#define PESDR1_HSSL2SET1 0x034c
93#define PESDR1_HSSL2SET2 0x034d
94#define PESDR1_HSSL2STS 0x034e
95#define PESDR1_HSSL3SET1 0x034f
96#define PESDR1_HSSL3SET2 0x0350
97#define PESDR1_HSSL3STS 0x0351
98#define PESDR1_HSSCTLSET 0x0352
99#define PESDR1_LANE_ABCD 0x0353
100
101#define PESDR2_UTLSET1 0x0370
102#define PESDR2_UTLSET2 0x0371
103#define PESDR2_DLPSET 0x0372
104#define PESDR2_LOOP 0x0373
105#define PESDR2_RCSSET 0x0374
106#define PESDR2_RCSSTS 0x0375
107#define PESDR2_HSSL0SET1 0x0376
108#define PESDR2_HSSL0SET2 0x0377
109#define PESDR2_HSSL0STS 0x0378
110#define PESDR2_HSSL1SET1 0x0379
111#define PESDR2_HSSL1SET2 0x037a
112#define PESDR2_HSSL1STS 0x037b
113#define PESDR2_HSSL2SET1 0x037c
114#define PESDR2_HSSL2SET2 0x037d
115#define PESDR2_HSSL2STS 0x037e
116#define PESDR2_HSSL3SET1 0x037f
117#define PESDR2_HSSL3SET2 0x0380
118#define PESDR2_HSSL3STS 0x0381
119#define PESDR2_HSSCTLSET 0x0382
120#define PESDR2_LANE_ABCD 0x0383
121
122/*
123 * UTL register offsets
124 */
125#define PEUTL_PBBSZ 0x20
126#define PEUTL_OPDBSZ 0x68
127#define PEUTL_IPHBSZ 0x70
128#define PEUTL_IPDBSZ 0x78
129#define PEUTL_OUTTR 0x90
130#define PEUTL_INTR 0x98
131#define PEUTL_PCTL 0xa0
132#define PEUTL_RCIRQEN 0xb8
133
134/*
135 * Config space register offsets
136 */
137#define PECFG_BAR0LMPA 0x210
138#define PECFG_BAR0HMPA 0x214
139#define PECFG_PIMEN 0x33c
140#define PECFG_PIM0LAL 0x340
141#define PECFG_PIM0LAH 0x344
142#define PECFG_POM0LAL 0x380
143#define PECFG_POM0LAH 0x384
144
145int ppc440spe_init_pcie(void);
146int ppc440spe_init_pcie_rootport(int port);
147void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
148
149#endif /* __PPC_SYSLIB_PPC440SPE_PCIE_H */
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index 0b435633a0d1..aa4165144ec2 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -38,6 +38,7 @@ extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__ ((weak));
38#define IRQ_MASK_UICx(irq) (1 << (31 - ((irq) & 0x1f))) 38#define IRQ_MASK_UICx(irq) (1 << (31 - ((irq) & 0x1f)))
39#define IRQ_MASK_UIC1(irq) IRQ_MASK_UICx(irq) 39#define IRQ_MASK_UIC1(irq) IRQ_MASK_UICx(irq)
40#define IRQ_MASK_UIC2(irq) IRQ_MASK_UICx(irq) 40#define IRQ_MASK_UIC2(irq) IRQ_MASK_UICx(irq)
41#define IRQ_MASK_UIC3(irq) IRQ_MASK_UICx(irq)
41 42
42#define UIC_HANDLERS(n) \ 43#define UIC_HANDLERS(n) \
43static void ppc4xx_uic##n##_enable(unsigned int irq) \ 44static void ppc4xx_uic##n##_enable(unsigned int irq) \
@@ -88,7 +89,38 @@ static void ppc4xx_uic##n##_end(unsigned int irq) \
88 .end = ppc4xx_uic##n##_end, \ 89 .end = ppc4xx_uic##n##_end, \
89} \ 90} \
90 91
91#if NR_UICS == 3 92#if NR_UICS == 4
93#define ACK_UIC0_PARENT
94#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
95#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC2NC);
96#define ACK_UIC3_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC3NC);
97UIC_HANDLERS(0);
98UIC_HANDLERS(1);
99UIC_HANDLERS(2);
100UIC_HANDLERS(3);
101
102static int ppc4xx_pic_get_irq(struct pt_regs *regs)
103{
104 u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
105 if (uic0 & UIC0_UIC1NC)
106 return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
107 else if (uic0 & UIC0_UIC2NC)
108 return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
109 else if (uic0 & UIC0_UIC3NC)
110 return 128 - ffs(mfdcr(DCRN_UIC_MSR(UIC3)));
111 else
112 return uic0 ? 32 - ffs(uic0) : -1;
113}
114
115static void __init ppc4xx_pic_impl_init(void)
116{
117 /* Enable cascade interrupts in UIC0 */
118 ppc_cached_irq_mask[0] |= UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC;
119 mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC);
120 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
121}
122
123#elif NR_UICS == 3
92#define ACK_UIC0_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC); 124#define ACK_UIC0_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
93#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC); 125#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
94#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC); 126#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
@@ -170,6 +202,9 @@ static struct ppc4xx_uic_impl {
170 { .decl = DECLARE_UIC(1), .base = UIC1 }, 202 { .decl = DECLARE_UIC(1), .base = UIC1 },
171#if NR_UICS > 2 203#if NR_UICS > 2
172 { .decl = DECLARE_UIC(2), .base = UIC2 }, 204 { .decl = DECLARE_UIC(2), .base = UIC2 },
205#if NR_UICS > 3
206 { .decl = DECLARE_UIC(3), .base = UIC3 },
207#endif
173#endif 208#endif
174#endif 209#endif
175}; 210};
diff --git a/arch/ppc/syslib/ppc85xx_rio.c b/arch/ppc/syslib/ppc85xx_rio.c
new file mode 100644
index 000000000000..297f3b549177
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.c
@@ -0,0 +1,938 @@
1/*
2 * MPC85xx RapidIO support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/dma-mapping.h>
18#include <linux/interrupt.h>
19#include <linux/rio.h>
20#include <linux/rio_drv.h>
21
22#include <asm/io.h>
23
24#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
25#define RIO_ATMU_REGS_OFFSET 0x10c00
26#define RIO_MSG_REGS_OFFSET 0x11000
27#define RIO_MAINT_WIN_SIZE 0x400000
28#define RIO_DBELL_WIN_SIZE 0x1000
29
30#define RIO_MSG_OMR_MUI 0x00000002
31#define RIO_MSG_OSR_TE 0x00000080
32#define RIO_MSG_OSR_QOI 0x00000020
33#define RIO_MSG_OSR_QFI 0x00000010
34#define RIO_MSG_OSR_MUB 0x00000004
35#define RIO_MSG_OSR_EOMI 0x00000002
36#define RIO_MSG_OSR_QEI 0x00000001
37
38#define RIO_MSG_IMR_MI 0x00000002
39#define RIO_MSG_ISR_TE 0x00000080
40#define RIO_MSG_ISR_QFI 0x00000010
41#define RIO_MSG_ISR_DIQI 0x00000001
42
43#define RIO_MSG_DESC_SIZE 32
44#define RIO_MSG_BUFFER_SIZE 4096
45#define RIO_MIN_TX_RING_SIZE 2
46#define RIO_MAX_TX_RING_SIZE 2048
47#define RIO_MIN_RX_RING_SIZE 2
48#define RIO_MAX_RX_RING_SIZE 2048
49
50#define DOORBELL_DMR_DI 0x00000002
51#define DOORBELL_DSR_TE 0x00000080
52#define DOORBELL_DSR_QFI 0x00000010
53#define DOORBELL_DSR_DIQI 0x00000001
54#define DOORBELL_TID_OFFSET 0x03
55#define DOORBELL_SID_OFFSET 0x05
56#define DOORBELL_INFO_OFFSET 0x06
57
58#define DOORBELL_MESSAGE_SIZE 0x08
59#define DBELL_SID(x) (*(u8 *)(x + DOORBELL_SID_OFFSET))
60#define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET))
61#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET))
62
63#define is_power_of_2(x) (((x) & ((x) - 1)) == 0)
64
65struct rio_atmu_regs {
66 u32 rowtar;
67 u32 pad1;
68 u32 rowbar;
69 u32 pad2;
70 u32 rowar;
71 u32 pad3[3];
72};
73
74struct rio_msg_regs {
75 u32 omr;
76 u32 osr;
77 u32 pad1;
78 u32 odqdpar;
79 u32 pad2;
80 u32 osar;
81 u32 odpr;
82 u32 odatr;
83 u32 odcr;
84 u32 pad3;
85 u32 odqepar;
86 u32 pad4[13];
87 u32 imr;
88 u32 isr;
89 u32 pad5;
90 u32 ifqdpar;
91 u32 pad6;
92 u32 ifqepar;
93 u32 pad7[250];
94 u32 dmr;
95 u32 dsr;
96 u32 pad8;
97 u32 dqdpar;
98 u32 pad9;
99 u32 dqepar;
100 u32 pad10[26];
101 u32 pwmr;
102 u32 pwsr;
103 u32 pad11;
104 u32 pwqbar;
105};
106
107struct rio_tx_desc {
108 u32 res1;
109 u32 saddr;
110 u32 dport;
111 u32 dattr;
112 u32 res2;
113 u32 res3;
114 u32 dwcnt;
115 u32 res4;
116};
117
118static u32 regs_win;
119static struct rio_atmu_regs *atmu_regs;
120static struct rio_atmu_regs *maint_atmu_regs;
121static struct rio_atmu_regs *dbell_atmu_regs;
122static u32 dbell_win;
123static u32 maint_win;
124static struct rio_msg_regs *msg_regs;
125
126static struct rio_dbell_ring {
127 void *virt;
128 dma_addr_t phys;
129} dbell_ring;
130
131static struct rio_msg_tx_ring {
132 void *virt;
133 dma_addr_t phys;
134 void *virt_buffer[RIO_MAX_TX_RING_SIZE];
135 dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
136 int tx_slot;
137 int size;
138 void *dev_id;
139} msg_tx_ring;
140
141static struct rio_msg_rx_ring {
142 void *virt;
143 dma_addr_t phys;
144 void *virt_buffer[RIO_MAX_RX_RING_SIZE];
145 int rx_slot;
146 int size;
147 void *dev_id;
148} msg_rx_ring;
149
150/**
151 * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
152 * @index: ID of RapidIO interface
153 * @destid: Destination ID of target device
154 * @data: 16-bit info field of RapidIO doorbell message
155 *
156 * Sends a MPC85xx doorbell message. Returns %0 on success or
157 * %-EINVAL on failure.
158 */
159static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
160{
161 pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
162 index, destid, data);
163 out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
164 out_be16((void *)(dbell_win), data);
165
166 return 0;
167}
168
169/**
170 * mpc85xx_local_config_read - Generate a MPC85xx local config space read
171 * @index: ID of RapdiIO interface
172 * @offset: Offset into configuration space
173 * @len: Length (in bytes) of the maintenance transaction
174 * @data: Value to be read into
175 *
176 * Generates a MPC85xx local configuration space read. Returns %0 on
177 * success or %-EINVAL on failure.
178 */
179static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
180{
181 pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
182 offset);
183 *data = in_be32((void *)(regs_win + offset));
184
185 return 0;
186}
187
188/**
189 * mpc85xx_local_config_write - Generate a MPC85xx local config space write
190 * @index: ID of RapdiIO interface
191 * @offset: Offset into configuration space
192 * @len: Length (in bytes) of the maintenance transaction
193 * @data: Value to be written
194 *
195 * Generates a MPC85xx local configuration space write. Returns %0 on
196 * success or %-EINVAL on failure.
197 */
198static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
199{
200 pr_debug
201 ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
202 index, offset, data);
203 out_be32((void *)(regs_win + offset), data);
204
205 return 0;
206}
207
208/**
209 * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
210 * @index: ID of RapdiIO interface
211 * @destid: Destination ID of transaction
212 * @hopcount: Number of hops to target device
213 * @offset: Offset into configuration space
214 * @len: Length (in bytes) of the maintenance transaction
215 * @val: Location to be read into
216 *
217 * Generates a MPC85xx read maintenance transaction. Returns %0 on
218 * success or %-EINVAL on failure.
219 */
220static int
221mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
222 u32 * val)
223{
224 u8 *data;
225
226 pr_debug
227 ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
228 index, destid, hopcount, offset, len);
229 out_be32((void *)&maint_atmu_regs->rowtar,
230 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
231
232 data = (u8 *) maint_win + offset;
233 switch (len) {
234 case 1:
235 *val = in_8((u8 *) data);
236 break;
237 case 2:
238 *val = in_be16((u16 *) data);
239 break;
240 default:
241 *val = in_be32((u32 *) data);
242 break;
243 }
244
245 return 0;
246}
247
248/**
249 * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
250 * @index: ID of RapdiIO interface
251 * @destid: Destination ID of transaction
252 * @hopcount: Number of hops to target device
253 * @offset: Offset into configuration space
254 * @len: Length (in bytes) of the maintenance transaction
255 * @val: Value to be written
256 *
257 * Generates an MPC85xx write maintenance transaction. Returns %0 on
258 * success or %-EINVAL on failure.
259 */
260static int
261mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
262 int len, u32 val)
263{
264 u8 *data;
265 pr_debug
266 ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
267 index, destid, hopcount, offset, len, val);
268 out_be32((void *)&maint_atmu_regs->rowtar,
269 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
270
271 data = (u8 *) maint_win + offset;
272 switch (len) {
273 case 1:
274 out_8((u8 *) data, val);
275 break;
276 case 2:
277 out_be16((u16 *) data, val);
278 break;
279 default:
280 out_be32((u32 *) data, val);
281 break;
282 }
283
284 return 0;
285}
286
287/**
288 * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
289 * @mport: Master port with outbound message queue
290 * @rdev: Target of outbound message
291 * @mbox: Outbound mailbox
292 * @buffer: Message to add to outbound queue
293 * @len: Length of message
294 *
295 * Adds the @buffer message to the MPC85xx outbound message queue. Returns
296 * %0 on success or %-EINVAL on failure.
297 */
298int
299rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
300 void *buffer, size_t len)
301{
302 u32 omr;
303 struct rio_tx_desc *desc =
304 (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
305 int ret = 0;
306
307 pr_debug
308 ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
309 rdev->destid, mbox, (int)buffer, len);
310
311 if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
312 ret = -EINVAL;
313 goto out;
314 }
315
316 /* Copy and clear rest of buffer */
317 memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
318 if (len < (RIO_MAX_MSG_SIZE - 4))
319 memset((void *)((u32) msg_tx_ring.
320 virt_buffer[msg_tx_ring.tx_slot] + len), 0,
321 RIO_MAX_MSG_SIZE - len);
322
323 /* Set mbox field for message */
324 desc->dport = mbox & 0x3;
325
326 /* Enable EOMI interrupt, set priority, and set destid */
327 desc->dattr = 0x28000000 | (rdev->destid << 2);
328
329 /* Set transfer size aligned to next power of 2 (in double words) */
330 desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
331
332 /* Set snooping and source buffer address */
333 desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
334
335 /* Increment enqueue pointer */
336 omr = in_be32((void *)&msg_regs->omr);
337 out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
338
339 /* Go to next descriptor */
340 if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
341 msg_tx_ring.tx_slot = 0;
342
343 out:
344 return ret;
345}
346
347EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
348
349/**
350 * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
351 * @irq: Linux interrupt number
352 * @dev_instance: Pointer to interrupt-specific data
353 * @regs: Register context
354 *
355 * Handles outbound message interrupts. Executes a register outbound
356 * mailbox event handler and acks the interrupt occurence.
357 */
358static irqreturn_t
359mpc85xx_rio_tx_handler(int irq, void *dev_instance, struct pt_regs *regs)
360{
361 int osr;
362 struct rio_mport *port = (struct rio_mport *)dev_instance;
363
364 osr = in_be32((void *)&msg_regs->osr);
365
366 if (osr & RIO_MSG_OSR_TE) {
367 pr_info("RIO: outbound message transmission error\n");
368 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
369 goto out;
370 }
371
372 if (osr & RIO_MSG_OSR_QOI) {
373 pr_info("RIO: outbound message queue overflow\n");
374 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
375 goto out;
376 }
377
378 if (osr & RIO_MSG_OSR_EOMI) {
379 u32 dqp = in_be32((void *)&msg_regs->odqdpar);
380 int slot = (dqp - msg_tx_ring.phys) >> 5;
381 port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
382
383 /* Ack the end-of-message interrupt */
384 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
385 }
386
387 out:
388 return IRQ_HANDLED;
389}
390
391/**
392 * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
393 * @mport: Master port implementing the outbound message unit
394 * @dev_id: Device specific pointer to pass on event
395 * @mbox: Mailbox to open
396 * @entries: Number of entries in the outbound mailbox ring
397 *
398 * Initializes buffer ring, request the outbound message interrupt,
399 * and enables the outbound message unit. Returns %0 on success and
400 * %-EINVAL or %-ENOMEM on failure.
401 */
402int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
403{
404 int i, j, rc = 0;
405
406 if ((entries < RIO_MIN_TX_RING_SIZE) ||
407 (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
408 rc = -EINVAL;
409 goto out;
410 }
411
412 /* Initialize shadow copy ring */
413 msg_tx_ring.dev_id = dev_id;
414 msg_tx_ring.size = entries;
415
416 for (i = 0; i < msg_tx_ring.size; i++) {
417 if (!
418 (msg_tx_ring.virt_buffer[i] =
419 dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
420 &msg_tx_ring.phys_buffer[i],
421 GFP_KERNEL))) {
422 rc = -ENOMEM;
423 for (j = 0; j < msg_tx_ring.size; j++)
424 if (msg_tx_ring.virt_buffer[j])
425 dma_free_coherent(NULL,
426 RIO_MSG_BUFFER_SIZE,
427 msg_tx_ring.
428 virt_buffer[j],
429 msg_tx_ring.
430 phys_buffer[j]);
431 goto out;
432 }
433 }
434
435 /* Initialize outbound message descriptor ring */
436 if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
437 msg_tx_ring.size *
438 RIO_MSG_DESC_SIZE,
439 &msg_tx_ring.phys,
440 GFP_KERNEL))) {
441 rc = -ENOMEM;
442 goto out_dma;
443 }
444 memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
445 msg_tx_ring.tx_slot = 0;
446
447 /* Point dequeue/enqueue pointers at first entry in ring */
448 out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
449 out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
450
451 /* Configure for snooping */
452 out_be32((void *)&msg_regs->osar, 0x00000004);
453
454 /* Clear interrupt status */
455 out_be32((void *)&msg_regs->osr, 0x000000b3);
456
457 /* Hook up outbound message handler */
458 if ((rc =
459 request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
460 "msg_tx", (void *)mport)) < 0)
461 goto out_irq;
462
463 /*
464 * Configure outbound message unit
465 * Snooping
466 * Interrupts (all enabled, except QEIE)
467 * Chaining mode
468 * Disable
469 */
470 out_be32((void *)&msg_regs->omr, 0x00100220);
471
472 /* Set number of entries */
473 out_be32((void *)&msg_regs->omr,
474 in_be32((void *)&msg_regs->omr) |
475 ((get_bitmask_order(entries) - 2) << 12));
476
477 /* Now enable the unit */
478 out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
479
480 out:
481 return rc;
482
483 out_irq:
484 dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
485 msg_tx_ring.virt, msg_tx_ring.phys);
486
487 out_dma:
488 for (i = 0; i < msg_tx_ring.size; i++)
489 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
490 msg_tx_ring.virt_buffer[i],
491 msg_tx_ring.phys_buffer[i]);
492
493 return rc;
494}
495
496/**
497 * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
498 * @mport: Master port implementing the outbound message unit
499 * @mbox: Mailbox to close
500 *
501 * Disables the outbound message unit, free all buffers, and
502 * frees the outbound message interrupt.
503 */
504void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
505{
506 /* Disable inbound message unit */
507 out_be32((void *)&msg_regs->omr, 0);
508
509 /* Free ring */
510 dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
511 msg_tx_ring.virt, msg_tx_ring.phys);
512
513 /* Free interrupt */
514 free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
515}
516
517/**
518 * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
519 * @irq: Linux interrupt number
520 * @dev_instance: Pointer to interrupt-specific data
521 * @regs: Register context
522 *
523 * Handles inbound message interrupts. Executes a registered inbound
524 * mailbox event handler and acks the interrupt occurence.
525 */
526static irqreturn_t
527mpc85xx_rio_rx_handler(int irq, void *dev_instance, struct pt_regs *regs)
528{
529 int isr;
530 struct rio_mport *port = (struct rio_mport *)dev_instance;
531
532 isr = in_be32((void *)&msg_regs->isr);
533
534 if (isr & RIO_MSG_ISR_TE) {
535 pr_info("RIO: inbound message reception error\n");
536 out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
537 goto out;
538 }
539
540 /* XXX Need to check/dispatch until queue empty */
541 if (isr & RIO_MSG_ISR_DIQI) {
542 /*
543 * We implement *only* mailbox 0, but can receive messages
544 * for any mailbox/letter to that mailbox destination. So,
545 * make the callback with an unknown/invalid mailbox number
546 * argument.
547 */
548 port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
549
550 /* Ack the queueing interrupt */
551 out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
552 }
553
554 out:
555 return IRQ_HANDLED;
556}
557
558/**
559 * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
560 * @mport: Master port implementing the inbound message unit
561 * @dev_id: Device specific pointer to pass on event
562 * @mbox: Mailbox to open
563 * @entries: Number of entries in the inbound mailbox ring
564 *
565 * Initializes buffer ring, request the inbound message interrupt,
566 * and enables the inbound message unit. Returns %0 on success
567 * and %-EINVAL or %-ENOMEM on failure.
568 */
569int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
570{
571 int i, rc = 0;
572
573 if ((entries < RIO_MIN_RX_RING_SIZE) ||
574 (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
575 rc = -EINVAL;
576 goto out;
577 }
578
579 /* Initialize client buffer ring */
580 msg_rx_ring.dev_id = dev_id;
581 msg_rx_ring.size = entries;
582 msg_rx_ring.rx_slot = 0;
583 for (i = 0; i < msg_rx_ring.size; i++)
584 msg_rx_ring.virt_buffer[i] = NULL;
585
586 /* Initialize inbound message ring */
587 if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
588 msg_rx_ring.size *
589 RIO_MAX_MSG_SIZE,
590 &msg_rx_ring.phys,
591 GFP_KERNEL))) {
592 rc = -ENOMEM;
593 goto out;
594 }
595
596 /* Point dequeue/enqueue pointers at first entry in ring */
597 out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
598 out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
599
600 /* Clear interrupt status */
601 out_be32((void *)&msg_regs->isr, 0x00000091);
602
603 /* Hook up inbound message handler */
604 if ((rc =
605 request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
606 "msg_rx", (void *)mport)) < 0) {
607 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
608 msg_tx_ring.virt_buffer[i],
609 msg_tx_ring.phys_buffer[i]);
610 goto out;
611 }
612
613 /*
614 * Configure inbound message unit:
615 * Snooping
616 * 4KB max message size
617 * Unmask all interrupt sources
618 * Disable
619 */
620 out_be32((void *)&msg_regs->imr, 0x001b0060);
621
622 /* Set number of queue entries */
623 out_be32((void *)&msg_regs->imr,
624 in_be32((void *)&msg_regs->imr) |
625 ((get_bitmask_order(entries) - 2) << 12));
626
627 /* Now enable the unit */
628 out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
629
630 out:
631 return rc;
632}
633
634/**
635 * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
636 * @mport: Master port implementing the inbound message unit
637 * @mbox: Mailbox to close
638 *
639 * Disables the inbound message unit, free all buffers, and
640 * frees the inbound message interrupt.
641 */
642void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
643{
644 /* Disable inbound message unit */
645 out_be32((void *)&msg_regs->imr, 0);
646
647 /* Free ring */
648 dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
649 msg_rx_ring.virt, msg_rx_ring.phys);
650
651 /* Free interrupt */
652 free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
653}
654
655/**
656 * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
657 * @mport: Master port implementing the inbound message unit
658 * @mbox: Inbound mailbox number
659 * @buf: Buffer to add to inbound queue
660 *
661 * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
662 * %0 on success or %-EINVAL on failure.
663 */
664int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
665{
666 int rc = 0;
667
668 pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
669 msg_rx_ring.rx_slot);
670
671 if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
672 printk(KERN_ERR
673 "RIO: error adding inbound buffer %d, buffer exists\n",
674 msg_rx_ring.rx_slot);
675 rc = -EINVAL;
676 goto out;
677 }
678
679 msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
680 if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
681 msg_rx_ring.rx_slot = 0;
682
683 out:
684 return rc;
685}
686
687EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
688
689/**
690 * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
691 * @mport: Master port implementing the inbound message unit
692 * @mbox: Inbound mailbox number
693 *
694 * Gets the next available inbound message from the inbound message queue.
695 * A pointer to the message is returned on success or NULL on failure.
696 */
697void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
698{
699 u32 imr;
700 u32 phys_buf, virt_buf;
701 void *buf = NULL;
702 int buf_idx;
703
704 phys_buf = in_be32((void *)&msg_regs->ifqdpar);
705
706 /* If no more messages, then bail out */
707 if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
708 goto out2;
709
710 virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
711 buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
712 buf = msg_rx_ring.virt_buffer[buf_idx];
713
714 if (!buf) {
715 printk(KERN_ERR
716 "RIO: inbound message copy failed, no buffers\n");
717 goto out1;
718 }
719
720 /* Copy max message size, caller is expected to allocate that big */
721 memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
722
723 /* Clear the available buffer */
724 msg_rx_ring.virt_buffer[buf_idx] = NULL;
725
726 out1:
727 imr = in_be32((void *)&msg_regs->imr);
728 out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
729
730 out2:
731 return buf;
732}
733
734EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
735
736/**
737 * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
738 * @irq: Linux interrupt number
739 * @dev_instance: Pointer to interrupt-specific data
740 * @regs: Register context
741 *
742 * Handles doorbell interrupts. Parses a list of registered
743 * doorbell event handlers and executes a matching event handler.
744 */
745static irqreturn_t
746mpc85xx_rio_dbell_handler(int irq, void *dev_instance, struct pt_regs *regs)
747{
748 int dsr;
749 struct rio_mport *port = (struct rio_mport *)dev_instance;
750
751 dsr = in_be32((void *)&msg_regs->dsr);
752
753 if (dsr & DOORBELL_DSR_TE) {
754 pr_info("RIO: doorbell reception error\n");
755 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
756 goto out;
757 }
758
759 if (dsr & DOORBELL_DSR_QFI) {
760 pr_info("RIO: doorbell queue full\n");
761 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
762 goto out;
763 }
764
765 /* XXX Need to check/dispatch until queue empty */
766 if (dsr & DOORBELL_DSR_DIQI) {
767 u32 dmsg =
768 (u32) dbell_ring.virt +
769 (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
770 u32 dmr;
771 struct rio_dbell *dbell;
772 int found = 0;
773
774 pr_debug
775 ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
776 DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
777
778 list_for_each_entry(dbell, &port->dbells, node) {
779 if ((dbell->res->start <= DBELL_INF(dmsg)) &&
780 (dbell->res->end >= DBELL_INF(dmsg))) {
781 found = 1;
782 break;
783 }
784 }
785 if (found) {
786 dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg),
787 DBELL_INF(dmsg));
788 } else {
789 pr_debug
790 ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
791 DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
792 }
793 dmr = in_be32((void *)&msg_regs->dmr);
794 out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
795 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
796 }
797
798 out:
799 return IRQ_HANDLED;
800}
801
802/**
803 * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
804 * @mport: Master port implementing the inbound doorbell unit
805 *
806 * Initializes doorbell unit hardware and inbound DMA buffer
807 * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
808 * or %-ENOMEM on failure.
809 */
810static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
811{
812 int rc = 0;
813
814 /* Map outbound doorbell window immediately after maintenance window */
815 if (!(dbell_win =
816 (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
817 RIO_DBELL_WIN_SIZE))) {
818 printk(KERN_ERR
819 "RIO: unable to map outbound doorbell window\n");
820 rc = -ENOMEM;
821 goto out;
822 }
823
824 /* Initialize inbound doorbells */
825 if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
826 512 * DOORBELL_MESSAGE_SIZE,
827 &dbell_ring.phys,
828 GFP_KERNEL))) {
829 printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
830 rc = -ENOMEM;
831 iounmap((void *)dbell_win);
832 goto out;
833 }
834
835 /* Point dequeue/enqueue pointers at first entry in ring */
836 out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
837 out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
838
839 /* Clear interrupt status */
840 out_be32((void *)&msg_regs->dsr, 0x00000091);
841
842 /* Hook up doorbell handler */
843 if ((rc =
844 request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
845 "dbell_rx", (void *)mport) < 0)) {
846 iounmap((void *)dbell_win);
847 dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
848 dbell_ring.virt, dbell_ring.phys);
849 printk(KERN_ERR
850 "MPC85xx RIO: unable to request inbound doorbell irq");
851 goto out;
852 }
853
854 /* Configure doorbells for snooping, 512 entries, and enable */
855 out_be32((void *)&msg_regs->dmr, 0x00108161);
856
857 out:
858 return rc;
859}
860
861static char *cmdline = NULL;
862
863static int mpc85xx_rio_get_hdid(int index)
864{
865 /* XXX Need to parse multiple entries in some format */
866 if (!cmdline)
867 return -1;
868
869 return simple_strtol(cmdline, NULL, 0);
870}
871
872static int mpc85xx_rio_get_cmdline(char *s)
873{
874 if (!s)
875 return 0;
876
877 cmdline = s;
878 return 1;
879}
880
881__setup("riohdid=", mpc85xx_rio_get_cmdline);
882
883/**
884 * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
885 * @law_start: Starting physical address of RapidIO LAW
886 * @law_size: Size of RapidIO LAW
887 *
888 * Initializes MPC85xx RapidIO hardware interface, configures
889 * master port with system-specific info, and registers the
890 * master port with the RapidIO subsystem.
891 */
892void mpc85xx_rio_setup(int law_start, int law_size)
893{
894 struct rio_ops *ops;
895 struct rio_mport *port;
896
897 ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
898 ops->lcread = mpc85xx_local_config_read;
899 ops->lcwrite = mpc85xx_local_config_write;
900 ops->cread = mpc85xx_rio_config_read;
901 ops->cwrite = mpc85xx_rio_config_write;
902 ops->dsend = mpc85xx_rio_doorbell_send;
903
904 port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
905 port->id = 0;
906 port->index = 0;
907 INIT_LIST_HEAD(&port->dbells);
908 port->iores.start = law_start;
909 port->iores.end = law_start + law_size;
910 port->iores.flags = IORESOURCE_MEM;
911
912 rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
913 rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
914 rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
915 strcpy(port->name, "RIO0 mport");
916
917 port->ops = ops;
918 port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
919
920 rio_register_mport(port);
921
922 regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
923 atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
924 maint_atmu_regs = atmu_regs + 1;
925 dbell_atmu_regs = atmu_regs + 2;
926 msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
927
928 /* Configure maintenance transaction window */
929 out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
930 out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
931
932 maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
933
934 /* Configure outbound doorbell window */
935 out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
936 out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
937 mpc85xx_rio_doorbell_init(port);
938}
diff --git a/arch/ppc/syslib/ppc85xx_rio.h b/arch/ppc/syslib/ppc85xx_rio.h
new file mode 100644
index 000000000000..c0827a2c3eec
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.h
@@ -0,0 +1,21 @@
1/*
2 * MPC85xx RapidIO definitions
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
14#define __PPC_SYSLIB_PPC85XX_RIO_H
15
16#include <linux/config.h>
17#include <linux/init.h>
18
19extern void mpc85xx_rio_setup(int law_start, int law_size);
20
21#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 62ee86e80711..603f01190816 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -14,6 +14,7 @@
14 * option) any later version. 14 * option) any later version.
15 */ 15 */
16 16
17#include <linux/string.h>
17#include <asm/ppc_sys.h> 18#include <asm/ppc_sys.h>
18 19
19int (*ppc_sys_device_fixup) (struct platform_device * pdev); 20int (*ppc_sys_device_fixup) (struct platform_device * pdev);
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index 278da6ee62ea..1b9aa0d6a924 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -1335,10 +1335,8 @@ release_OF_resource(struct device_node* node, int index)
1335 if (!res) 1335 if (!res)
1336 return -ENODEV; 1336 return -ENODEV;
1337 1337
1338 if (res->name) { 1338 kfree(res->name);
1339 kfree(res->name); 1339 res->name = NULL;
1340 res->name = NULL;
1341 }
1342 release_resource(res); 1340 release_resource(res);
1343 kfree(res); 1341 kfree(res);
1344 1342
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index c1dc876bccab..e0dde24a72ce 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -203,8 +203,15 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
203 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) 203 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
204 break; 204 break;
205 } 205 }
206 vmlinux.size = (unsigned long)elf64ph->p_filesz; 206 vmlinux.size = (unsigned long)elf64ph->p_filesz +
207 vmlinux.memsize = (unsigned long)elf64ph->p_memsz; 207 (unsigned long)elf64ph->p_offset;
208 /* We need to claim the memsize plus the file offset since gzip
209 * will expand the header (file offset), then the kernel, then
210 * possible rubbish we don't care about. But the kernel bss must
211 * be claimed (it will be zero'd by the kernel itself)
212 */
213 vmlinux.memsize = (unsigned long)elf64ph->p_memsz +
214 (unsigned long)elf64ph->p_offset;
208 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); 215 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
209 vmlinux.addr = try_claim(vmlinux.memsize); 216 vmlinux.addr = try_claim(vmlinux.memsize);
210 if (vmlinux.addr == 0) { 217 if (vmlinux.addr == 0) {
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index ed876a5178ae..511af54e6230 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -30,19 +30,14 @@
30#include <linux/config.h> 30#include <linux/config.h>
31#include <linux/kprobes.h> 31#include <linux/kprobes.h>
32#include <linux/ptrace.h> 32#include <linux/ptrace.h>
33#include <linux/spinlock.h>
34#include <linux/preempt.h> 33#include <linux/preempt.h>
35#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
36#include <asm/kdebug.h> 35#include <asm/kdebug.h>
37#include <asm/sstep.h> 36#include <asm/sstep.h>
38 37
39static DECLARE_MUTEX(kprobe_mutex); 38static DECLARE_MUTEX(kprobe_mutex);
40 39DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
41static struct kprobe *current_kprobe; 40DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
42static unsigned long kprobe_status, kprobe_saved_msr;
43static struct kprobe *kprobe_prev;
44static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
45static struct pt_regs jprobe_saved_regs;
46 41
47int __kprobes arch_prepare_kprobe(struct kprobe *p) 42int __kprobes arch_prepare_kprobe(struct kprobe *p)
48{ 43{
@@ -108,20 +103,28 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
108 regs->nip = (unsigned long)p->ainsn.insn; 103 regs->nip = (unsigned long)p->ainsn.insn;
109} 104}
110 105
111static inline void save_previous_kprobe(void) 106static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
107{
108 kcb->prev_kprobe.kp = kprobe_running();
109 kcb->prev_kprobe.status = kcb->kprobe_status;
110 kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
111}
112
113static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
112{ 114{
113 kprobe_prev = current_kprobe; 115 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
114 kprobe_status_prev = kprobe_status; 116 kcb->kprobe_status = kcb->prev_kprobe.status;
115 kprobe_saved_msr_prev = kprobe_saved_msr; 117 kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
116} 118}
117 119
118static inline void restore_previous_kprobe(void) 120static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
121 struct kprobe_ctlblk *kcb)
119{ 122{
120 current_kprobe = kprobe_prev; 123 __get_cpu_var(current_kprobe) = p;
121 kprobe_status = kprobe_status_prev; 124 kcb->kprobe_saved_msr = regs->msr;
122 kprobe_saved_msr = kprobe_saved_msr_prev;
123} 125}
124 126
127/* Called with kretprobe_lock held */
125void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, 128void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
126 struct pt_regs *regs) 129 struct pt_regs *regs)
127{ 130{
@@ -145,19 +148,24 @@ static inline int kprobe_handler(struct pt_regs *regs)
145 struct kprobe *p; 148 struct kprobe *p;
146 int ret = 0; 149 int ret = 0;
147 unsigned int *addr = (unsigned int *)regs->nip; 150 unsigned int *addr = (unsigned int *)regs->nip;
151 struct kprobe_ctlblk *kcb;
152
153 /*
154 * We don't want to be preempted for the entire
155 * duration of kprobe processing
156 */
157 preempt_disable();
158 kcb = get_kprobe_ctlblk();
148 159
149 /* Check we're not actually recursing */ 160 /* Check we're not actually recursing */
150 if (kprobe_running()) { 161 if (kprobe_running()) {
151 /* We *are* holding lock here, so this is safe.
152 Disarm the probe we just hit, and ignore it. */
153 p = get_kprobe(addr); 162 p = get_kprobe(addr);
154 if (p) { 163 if (p) {
155 kprobe_opcode_t insn = *p->ainsn.insn; 164 kprobe_opcode_t insn = *p->ainsn.insn;
156 if (kprobe_status == KPROBE_HIT_SS && 165 if (kcb->kprobe_status == KPROBE_HIT_SS &&
157 is_trap(insn)) { 166 is_trap(insn)) {
158 regs->msr &= ~MSR_SE; 167 regs->msr &= ~MSR_SE;
159 regs->msr |= kprobe_saved_msr; 168 regs->msr |= kcb->kprobe_saved_msr;
160 unlock_kprobes();
161 goto no_kprobe; 169 goto no_kprobe;
162 } 170 }
163 /* We have reentered the kprobe_handler(), since 171 /* We have reentered the kprobe_handler(), since
@@ -166,27 +174,24 @@ static inline int kprobe_handler(struct pt_regs *regs)
166 * just single step on the instruction of the new probe 174 * just single step on the instruction of the new probe
167 * without calling any user handlers. 175 * without calling any user handlers.
168 */ 176 */
169 save_previous_kprobe(); 177 save_previous_kprobe(kcb);
170 current_kprobe = p; 178 set_current_kprobe(p, regs, kcb);
171 kprobe_saved_msr = regs->msr; 179 kcb->kprobe_saved_msr = regs->msr;
172 p->nmissed++; 180 p->nmissed++;
173 prepare_singlestep(p, regs); 181 prepare_singlestep(p, regs);
174 kprobe_status = KPROBE_REENTER; 182 kcb->kprobe_status = KPROBE_REENTER;
175 return 1; 183 return 1;
176 } else { 184 } else {
177 p = current_kprobe; 185 p = __get_cpu_var(current_kprobe);
178 if (p->break_handler && p->break_handler(p, regs)) { 186 if (p->break_handler && p->break_handler(p, regs)) {
179 goto ss_probe; 187 goto ss_probe;
180 } 188 }
181 } 189 }
182 /* If it's not ours, can't be delete race, (we hold lock). */
183 goto no_kprobe; 190 goto no_kprobe;
184 } 191 }
185 192
186 lock_kprobes();
187 p = get_kprobe(addr); 193 p = get_kprobe(addr);
188 if (!p) { 194 if (!p) {
189 unlock_kprobes();
190 if (*addr != BREAKPOINT_INSTRUCTION) { 195 if (*addr != BREAKPOINT_INSTRUCTION) {
191 /* 196 /*
192 * PowerPC has multiple variants of the "trap" 197 * PowerPC has multiple variants of the "trap"
@@ -209,24 +214,19 @@ static inline int kprobe_handler(struct pt_regs *regs)
209 goto no_kprobe; 214 goto no_kprobe;
210 } 215 }
211 216
212 kprobe_status = KPROBE_HIT_ACTIVE; 217 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
213 current_kprobe = p; 218 set_current_kprobe(p, regs, kcb);
214 kprobe_saved_msr = regs->msr;
215 if (p->pre_handler && p->pre_handler(p, regs)) 219 if (p->pre_handler && p->pre_handler(p, regs))
216 /* handler has already set things up, so skip ss setup */ 220 /* handler has already set things up, so skip ss setup */
217 return 1; 221 return 1;
218 222
219ss_probe: 223ss_probe:
220 prepare_singlestep(p, regs); 224 prepare_singlestep(p, regs);
221 kprobe_status = KPROBE_HIT_SS; 225 kcb->kprobe_status = KPROBE_HIT_SS;
222 /*
223 * This preempt_disable() matches the preempt_enable_no_resched()
224 * in post_kprobe_handler().
225 */
226 preempt_disable();
227 return 1; 226 return 1;
228 227
229no_kprobe: 228no_kprobe:
229 preempt_enable_no_resched();
230 return ret; 230 return ret;
231} 231}
232 232
@@ -251,9 +251,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
251 struct kretprobe_instance *ri = NULL; 251 struct kretprobe_instance *ri = NULL;
252 struct hlist_head *head; 252 struct hlist_head *head;
253 struct hlist_node *node, *tmp; 253 struct hlist_node *node, *tmp;
254 unsigned long orig_ret_address = 0; 254 unsigned long flags, orig_ret_address = 0;
255 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; 255 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
256 256
257 spin_lock_irqsave(&kretprobe_lock, flags);
257 head = kretprobe_inst_table_head(current); 258 head = kretprobe_inst_table_head(current);
258 259
259 /* 260 /*
@@ -292,12 +293,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
292 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); 293 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
293 regs->nip = orig_ret_address; 294 regs->nip = orig_ret_address;
294 295
295 unlock_kprobes(); 296 reset_current_kprobe();
297 spin_unlock_irqrestore(&kretprobe_lock, flags);
298 preempt_enable_no_resched();
296 299
297 /* 300 /*
298 * By returning a non-zero value, we are telling 301 * By returning a non-zero value, we are telling
299 * kprobe_handler() that we have handled unlocking 302 * kprobe_handler() that we don't want the post_handler
300 * and re-enabling preemption. 303 * to run (and have re-enabled preemption)
301 */ 304 */
302 return 1; 305 return 1;
303} 306}
@@ -323,23 +326,26 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
323 326
324static inline int post_kprobe_handler(struct pt_regs *regs) 327static inline int post_kprobe_handler(struct pt_regs *regs)
325{ 328{
326 if (!kprobe_running()) 329 struct kprobe *cur = kprobe_running();
330 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
331
332 if (!cur)
327 return 0; 333 return 0;
328 334
329 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { 335 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
330 kprobe_status = KPROBE_HIT_SSDONE; 336 kcb->kprobe_status = KPROBE_HIT_SSDONE;
331 current_kprobe->post_handler(current_kprobe, regs, 0); 337 cur->post_handler(cur, regs, 0);
332 } 338 }
333 339
334 resume_execution(current_kprobe, regs); 340 resume_execution(cur, regs);
335 regs->msr |= kprobe_saved_msr; 341 regs->msr |= kcb->kprobe_saved_msr;
336 342
337 /*Restore back the original saved kprobes variables and continue. */ 343 /*Restore back the original saved kprobes variables and continue. */
338 if (kprobe_status == KPROBE_REENTER) { 344 if (kcb->kprobe_status == KPROBE_REENTER) {
339 restore_previous_kprobe(); 345 restore_previous_kprobe(kcb);
340 goto out; 346 goto out;
341 } 347 }
342 unlock_kprobes(); 348 reset_current_kprobe();
343out: 349out:
344 preempt_enable_no_resched(); 350 preempt_enable_no_resched();
345 351
@@ -354,19 +360,20 @@ out:
354 return 1; 360 return 1;
355} 361}
356 362
357/* Interrupts disabled, kprobe_lock held. */
358static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 363static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
359{ 364{
360 if (current_kprobe->fault_handler 365 struct kprobe *cur = kprobe_running();
361 && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) 366 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
367
368 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
362 return 1; 369 return 1;
363 370
364 if (kprobe_status & KPROBE_HIT_SS) { 371 if (kcb->kprobe_status & KPROBE_HIT_SS) {
365 resume_execution(current_kprobe, regs); 372 resume_execution(cur, regs);
366 regs->msr &= ~MSR_SE; 373 regs->msr &= ~MSR_SE;
367 regs->msr |= kprobe_saved_msr; 374 regs->msr |= kcb->kprobe_saved_msr;
368 375
369 unlock_kprobes(); 376 reset_current_kprobe();
370 preempt_enable_no_resched(); 377 preempt_enable_no_resched();
371 } 378 }
372 return 0; 379 return 0;
@@ -381,11 +388,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
381 struct die_args *args = (struct die_args *)data; 388 struct die_args *args = (struct die_args *)data;
382 int ret = NOTIFY_DONE; 389 int ret = NOTIFY_DONE;
383 390
384 /*
385 * Interrupts are not disabled here. We need to disable
386 * preemption, because kprobe_running() uses smp_processor_id().
387 */
388 preempt_disable();
389 switch (val) { 391 switch (val) {
390 case DIE_BPT: 392 case DIE_BPT:
391 if (kprobe_handler(args->regs)) 393 if (kprobe_handler(args->regs))
@@ -396,22 +398,25 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
396 ret = NOTIFY_STOP; 398 ret = NOTIFY_STOP;
397 break; 399 break;
398 case DIE_PAGE_FAULT: 400 case DIE_PAGE_FAULT:
401 /* kprobe_running() needs smp_processor_id() */
402 preempt_disable();
399 if (kprobe_running() && 403 if (kprobe_running() &&
400 kprobe_fault_handler(args->regs, args->trapnr)) 404 kprobe_fault_handler(args->regs, args->trapnr))
401 ret = NOTIFY_STOP; 405 ret = NOTIFY_STOP;
406 preempt_enable();
402 break; 407 break;
403 default: 408 default:
404 break; 409 break;
405 } 410 }
406 preempt_enable_no_resched();
407 return ret; 411 return ret;
408} 412}
409 413
410int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 414int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
411{ 415{
412 struct jprobe *jp = container_of(p, struct jprobe, kp); 416 struct jprobe *jp = container_of(p, struct jprobe, kp);
417 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
413 418
414 memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs)); 419 memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
415 420
416 /* setup return addr to the jprobe handler routine */ 421 /* setup return addr to the jprobe handler routine */
417 regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); 422 regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
@@ -431,12 +436,15 @@ void __kprobes jprobe_return_end(void)
431 436
432int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 437int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
433{ 438{
439 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
440
434 /* 441 /*
435 * FIXME - we should ideally be validating that we got here 'cos 442 * FIXME - we should ideally be validating that we got here 'cos
436 * of the "trap" in jprobe_return() above, before restoring the 443 * of the "trap" in jprobe_return() above, before restoring the
437 * saved regs... 444 * saved regs...
438 */ 445 */
439 memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs)); 446 memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
447 preempt_enable_no_resched();
440 return 1; 448 return 1;
441} 449}
442 450
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c
index e86155770bbc..3e7b2f28ec83 100644
--- a/arch/ppc64/kernel/lparcfg.c
+++ b/arch/ppc64/kernel/lparcfg.c
@@ -599,9 +599,7 @@ int __init lparcfg_init(void)
599void __exit lparcfg_cleanup(void) 599void __exit lparcfg_cleanup(void)
600{ 600{
601 if (proc_ppc64_lparcfg) { 601 if (proc_ppc64_lparcfg) {
602 if (proc_ppc64_lparcfg->data) { 602 kfree(proc_ppc64_lparcfg->data);
603 kfree(proc_ppc64_lparcfg->data);
604 }
605 remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); 603 remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
606 } 604 }
607} 605}
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c
index 215bf8900304..2edc947f7c44 100644
--- a/arch/ppc64/kernel/scanlog.c
+++ b/arch/ppc64/kernel/scanlog.c
@@ -225,8 +225,7 @@ int __init scanlog_init(void)
225void __exit scanlog_cleanup(void) 225void __exit scanlog_cleanup(void)
226{ 226{
227 if (proc_ppc64_scan_log_dump) { 227 if (proc_ppc64_scan_log_dump) {
228 if (proc_ppc64_scan_log_dump->data) 228 kfree(proc_ppc64_scan_log_dump->data);
229 kfree(proc_ppc64_scan_log_dump->data);
230 remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent); 229 remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
231 } 230 }
232} 231}
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 98db30481d97..73a09a6ee6c8 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -76,9 +76,7 @@ AFLAGS += $(aflags-y)
76OBJCOPYFLAGS := -O binary 76OBJCOPYFLAGS := -O binary
77LDFLAGS_vmlinux := -e start 77LDFLAGS_vmlinux := -e start
78 78
79head-$(CONFIG_ARCH_S390_31) += arch/$(ARCH)/kernel/head.o 79head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
80head-$(CONFIG_ARCH_S390X) += arch/$(ARCH)/kernel/head64.o
81head-y += arch/$(ARCH)/kernel/init_task.o
82 80
83core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \ 81core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \
84 arch/$(ARCH)/appldata/ 82 arch/$(ARCH)/appldata/
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 8584dd823218..7434c32bc631 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -8,9 +8,7 @@ obj-y := bitmap.o traps.o time.o process.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o 9 semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
10 10
11extra-$(CONFIG_ARCH_S390_31) += head.o 11extra-y += head.o init_task.o vmlinux.lds
12extra-$(CONFIG_ARCH_S390X) += head64.o
13extra-y += init_task.o vmlinux.lds
14 12
15obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 13obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
16obj-$(CONFIG_SMP) += smp.o 14obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 9b30f4cf32c4..27b07730b7b8 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -288,7 +288,7 @@ sysc_sigpending:
288 bo BASED(sysc_restart) 288 bo BASED(sysc_restart)
289 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 289 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
290 bo BASED(sysc_singlestep) 290 bo BASED(sysc_singlestep)
291 b BASED(sysc_leave) # out of here, do NOT recheck 291 b BASED(sysc_work_loop)
292 292
293# 293#
294# _TIF_RESTART_SVC is set, set up registers and restart svc 294# _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -645,7 +645,7 @@ io_sigpending:
645 l %r1,BASED(.Ldo_signal) 645 l %r1,BASED(.Ldo_signal)
646 basr %r14,%r1 # call do_signal 646 basr %r14,%r1 # call do_signal
647 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 647 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
648 b BASED(io_leave) # out of here, do NOT recheck 648 b BASED(io_work_loop)
649 649
650/* 650/*
651 * External interrupt handler routine 651 * External interrupt handler routine
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7b9b4a2ba1d7..4eb71ffcf484 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -283,7 +283,7 @@ sysc_sigpending:
283 jo sysc_restart 283 jo sysc_restart
284 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP 284 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
285 jo sysc_singlestep 285 jo sysc_singlestep
286 j sysc_leave # out of here, do NOT recheck 286 j sysc_work_loop
287 287
288# 288#
289# _TIF_RESTART_SVC is set, set up registers and restart svc 289# _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -684,7 +684,7 @@ io_sigpending:
684 slgr %r3,%r3 # clear *oldset 684 slgr %r3,%r3 # clear *oldset
685 brasl %r14,do_signal # call do_signal 685 brasl %r14,do_signal # call do_signal
686 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 686 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
687 j sysc_leave # out of here, do NOT recheck 687 j io_work_loop
688 688
689/* 689/*
690 * External interrupt handler routine 690 * External interrupt handler routine
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 039354d72348..d31a97c89f68 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,11 +1,12 @@
1/* 1/*
2 * arch/s390/kernel/head.S 2 * arch/s390/kernel/head.S
3 * 3 *
4 * S390 version 4 * (C) Copyright IBM Corp. 1999, 2005
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
6 * Author(s): Hartmut Penner (hp@de.ibm.com), 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky (schwidefsky@de.ibm.com), 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * Rob van der Heij (rvdhei@iae.nl) 8 * Rob van der Heij <rvdhei@iae.nl>
9 * Heiko Carstens <heiko.carstens@de.ibm.com>
9 * 10 *
10 * There are 5 different IPL methods 11 * There are 5 different IPL methods
11 * 1) load the image directly into ram at address 0 and do an PSW restart 12 * 1) load the image directly into ram at address 0 and do an PSW restart
@@ -19,12 +20,7 @@
19 * 5) direct call of start by the SALIPL loader 20 * 5) direct call of start by the SALIPL loader
20 * We use the cpuid to distinguish between VM and native ipl 21 * We use the cpuid to distinguish between VM and native ipl
21 * params for kernel are pushed to 0x10400 (see setup.h) 22 * params for kernel are pushed to 0x10400 (see setup.h)
22 23 *
23 Changes:
24 Okt 25 2000 <rvdheij@iae.nl>
25 added code to skip HDR and EOF to allow SL tape IPL (5 retries)
26 changed first CCW from rewind to backspace block
27
28 */ 24 */
29 25
30#include <linux/config.h> 26#include <linux/config.h>
@@ -34,6 +30,12 @@
34#include <asm/thread_info.h> 30#include <asm/thread_info.h>
35#include <asm/page.h> 31#include <asm/page.h>
36 32
33#ifdef CONFIG_ARCH_S390X
34#define ARCH_OFFSET 4
35#else
36#define ARCH_OFFSET 0
37#endif
38
37#ifndef CONFIG_IPL 39#ifndef CONFIG_IPL
38 .org 0 40 .org 0
39 .long 0x00080000,0x80000000+startup # Just a restart PSW 41 .long 0x00080000,0x80000000+startup # Just a restart PSW
@@ -201,7 +203,7 @@
201 ssch 0(%r3) # load chunk of 1600 bytes 203 ssch 0(%r3) # load chunk of 1600 bytes
202 bnz .Llderr 204 bnz .Llderr
203.Lwait4irq: 205.Lwait4irq:
204 mvc __LC_IO_NEW_PSW(8),.Lnewpsw # set up IO interrupt psw 206 mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
205 lpsw .Lwaitpsw 207 lpsw .Lwaitpsw
206.Lioint: 208.Lioint:
207 c %r1,0xb8 # compare subchannel number 209 c %r1,0xb8 # compare subchannel number
@@ -265,13 +267,13 @@ iplstart:
265 la %r2,IPL_BS # load start address 267 la %r2,IPL_BS # load start address
266 bas %r14,.Lloader # load rest of ipl image 268 bas %r14,.Lloader # load rest of ipl image
267 l %r12,.Lparm # pointer to parameter area 269 l %r12,.Lparm # pointer to parameter area
268 st %r1,IPL_DEVICE-PARMAREA(%r12) # store ipl device number 270 st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
269 271
270# 272#
271# load parameter file from ipl device 273# load parameter file from ipl device
272# 274#
273.Lagain1: 275.Lagain1:
274 l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp 276 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
275 bas %r14,.Lloader # load parameter file 277 bas %r14,.Lloader # load parameter file
276 ltr %r2,%r2 # got anything ? 278 ltr %r2,%r2 # got anything ?
277 bz .Lnopf 279 bz .Lnopf
@@ -279,7 +281,7 @@ iplstart:
279 bnh .Lnotrunc 281 bnh .Lnotrunc
280 la %r2,895 282 la %r2,895
281.Lnotrunc: 283.Lnotrunc:
282 l %r4,INITRD_START-PARMAREA(%r12) 284 l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
283 clc 0(3,%r4),.L_hdr # if it is HDRx 285 clc 0(3,%r4),.L_hdr # if it is HDRx
284 bz .Lagain1 # skip dataset header 286 bz .Lagain1 # skip dataset header
285 clc 0(3,%r4),.L_eof # if it is EOFx 287 clc 0(3,%r4),.L_eof # if it is EOFx
@@ -322,14 +324,14 @@ iplstart:
322# load ramdisk from ipl device 324# load ramdisk from ipl device
323# 325#
324.Lagain2: 326.Lagain2:
325 l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk 327 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
326 bas %r14,.Lloader # load ramdisk 328 bas %r14,.Lloader # load ramdisk
327 st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk 329 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
328 ltr %r2,%r2 330 ltr %r2,%r2
329 bnz .Lrdcont 331 bnz .Lrdcont
330 st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it 332 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
331.Lrdcont: 333.Lrdcont:
332 l %r2,INITRD_START-PARMAREA(%r12) 334 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
333 335
334 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx 336 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
335 bz .Lagain2 337 bz .Lagain2
@@ -432,10 +434,10 @@ start:
432 la %r3,1(%r3) 434 la %r3,1(%r3)
433.done: 435.done:
434 l %r1,.memsize 436 l %r1,.memsize
435 st %r3,0(%r1) 437 st %r3,ARCH_OFFSET(%r1)
436 slr %r0,%r0 438 slr %r0,%r0
437 st %r0,INITRD_SIZE-PARMAREA(%r11) 439 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
438 st %r0,INITRD_START-PARMAREA(%r11) 440 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
439 j startup # continue with startup 441 j startup # continue with startup
440.tbl: .long _ebcasc # translate table 442.tbl: .long _ebcasc # translate table
441.cmd: .long COMMAND_LINE # address of command line buffer 443.cmd: .long COMMAND_LINE # address of command line buffer
@@ -478,304 +480,23 @@ start:
478 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 480 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
479 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff 481 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
480 482
481# 483.macro GET_IPL_DEVICE
482# startup-code at 0x10000, running in real mode
483# this is called either by the ipl loader or directly by PSW restart
484# or linload or SALIPL
485#
486 .org 0x10000
487startup:basr %r13,0 # get base
488.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13)
489 basr %r14, %r1
490 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
491 la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
492 # move IPL device to lowcore
493 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
494
495#
496# clear bss memory
497#
498 l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
499 l %r3,.Lbss_end-.LPG1(%r13) # end of bss
500 sr %r3,%r2 # length of bss
501 sr %r4,%r4 #
502 sr %r5,%r5 # set src,length and pad to zero
503 sr %r0,%r0 #
504 mvcle %r2,%r4,0 # clear mem
505 jo .-4 # branch back, if not finish
506
507 l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
508.Lservicecall:
509 stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
510
511 stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
512 la %r1,0x200 # set bit 22
513 o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
514 st %r1,.Lcr-.LPG1(%r13)
515 lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
516
517 mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
518 la %r1, .Lsclph-.LPG1(%r13)
519 a %r1,__LC_EXT_NEW_PSW+4 # set handler
520 st %r1,__LC_EXT_NEW_PSW+4
521
522 la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
523 la %r1, .Lsccb-PARMAREA(%r4) # our sccb
524 .insn rre,0xb2200000,%r2,%r1 # service call
525 ipm %r1
526 srl %r1,28 # get cc code
527 xr %r3, %r3
528 chi %r1,3
529 be .Lfchunk-.LPG1(%r13) # leave
530 chi %r1,2
531 be .Lservicecall-.LPG1(%r13)
532 lpsw .Lwaitsclp-.LPG1(%r13)
533.Lsclph:
534 lh %r1,.Lsccbr-PARMAREA(%r4)
535 chi %r1,0x10 # 0x0010 is the sucess code
536 je .Lprocsccb # let's process the sccb
537 chi %r1,0x1f0
538 bne .Lfchunk-.LPG1(%r13) # unhandled error code
539 c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced
540 bne .Lfchunk-.LPG1(%r13) # if no, give up
541 l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
542 b .Lservicecall-.LPG1(%r13)
543.Lprocsccb:
544 lhi %r1,0
545 icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
546 jnz .Lscnd
547 lhi %r1,0x800 # otherwise report 2GB
548.Lscnd:
549 lhi %r3,0x800 # limit reported memory size to 2GB
550 cr %r1,%r3
551 jl .Lno2gb
552 lr %r1,%r3
553.Lno2gb:
554 xr %r3,%r3 # same logic
555 ic %r3,.Lscpa1-PARMAREA(%r4)
556 chi %r3,0x00
557 jne .Lcompmem
558 l %r3,.Lscpa2-PARMAREA(%r13)
559.Lcompmem:
560 mr %r2,%r1 # mem in MB on 128-bit
561 l %r1,.Lonemb-.LPG1(%r13)
562 mr %r2,%r1 # mem size in bytes in %r3
563 b .Lfchunk-.LPG1(%r13)
564
565 .align 4
566.Lget_ipl_device_addr:
567 .long .Lget_ipl_device
568.Lpmask:
569 .byte 0
570.align 8
571.Lpcext:.long 0x00080000,0x80000000
572.Lcr:
573 .long 0x00 # place holder for cr0
574.Lwaitsclp:
575 .long 0x020A0000
576 .long .Lsclph
577.Lrcp:
578 .int 0x00120001 # Read SCP forced code
579.Lrcp2:
580 .int 0x00020001 # Read SCP code
581.Lonemb:
582 .int 0x100000
583.Lfchunk:
584
585#
586# find memory chunks.
587#
588 lr %r9,%r3 # end of mem
589 mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
590 la %r1,1 # test in increments of 128KB
591 sll %r1,17
592 l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
593 slr %r4,%r4 # set start of chunk to zero
594 slr %r5,%r5 # set end of chunk to zero
595 slr %r6,%r6 # set access code to zero
596 la %r10, MEMORY_CHUNKS # number of chunks
597.Lloop:
598 tprot 0(%r5),0 # test protection of first byte
599 ipm %r7
600 srl %r7,28
601 clr %r6,%r7 # compare cc with last access code
602 be .Lsame-.LPG1(%r13)
603 b .Lchkmem-.LPG1(%r13)
604.Lsame:
605 ar %r5,%r1 # add 128KB to end of chunk
606 bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
607.Lchkmem: # > 2GB or tprot got a program check
608 clr %r4,%r5 # chunk size > 0?
609 be .Lchkloop-.LPG1(%r13)
610 st %r4,0(%r3) # store start address of chunk
611 lr %r0,%r5
612 slr %r0,%r4
613 st %r0,4(%r3) # store size of chunk
614 st %r6,8(%r3) # store type of chunk
615 la %r3,12(%r3)
616 l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
617 st %r5,0(%r4) # store last end to memory size
618 ahi %r10,-1 # update chunk number
619.Lchkloop:
620 lr %r6,%r7 # set access code to last cc
621 # we got an exception or we're starting a new
622 # chunk , we must check if we should
623 # still try to find valid memory (if we detected
624 # the amount of available storage), and if we
625 # have chunks left
626 xr %r0,%r0
627 clr %r0,%r9 # did we detect memory?
628 je .Ldonemem # if not, leave
629 chi %r10,0 # do we have chunks left?
630 je .Ldonemem
631 alr %r5,%r1 # add 128KB to end of chunk
632 lr %r4,%r5 # potential new chunk
633 clr %r5,%r9 # should we go on?
634 jl .Lloop
635.Ldonemem:
636 l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
637#
638# find out if we are running under VM
639#
640 stidp __LC_CPUID # store cpuid
641 tm __LC_CPUID,0xff # running under VM ?
642 bno .Lnovm-.LPG1(%r13)
643 oi 3(%r12),1 # set VM flag
644.Lnovm:
645 lh %r0,__LC_CPUID+4 # get cpu version
646 chi %r0,0x7490 # running on a P/390 ?
647 bne .Lnop390-.LPG1(%r13)
648 oi 3(%r12),4 # set P/390 flag
649.Lnop390:
650
651#
652# find out if we have an IEEE fpu
653#
654 mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
655 efpc %r0,0 # test IEEE extract fpc instruction
656 oi 3(%r12),2 # set IEEE fpu flag
657.Lchkfpu:
658
659#
660# find out if we have the CSP instruction
661#
662 mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
663 la %r0,0
664 lr %r1,%r0
665 la %r2,4
666 csp %r0,%r2 # Test CSP instruction
667 oi 3(%r12),8 # set CSP flag
668.Lchkcsp:
669
670#
671# find out if we have the MVPG instruction
672#
673 mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
674 sr %r0,%r0
675 la %r1,0
676 la %r2,0
677 mvpg %r1,%r2 # Test CSP instruction
678 oi 3(%r12),16 # set MVPG flag
679.Lchkmvpg:
680
681#
682# find out if we have the IDTE instruction
683#
684 mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
685 .long 0xb2b10000 # store facility list
686 tm 0xc8,0x08 # check bit for clearing-by-ASCE
687 bno .Lchkidte-.LPG1(%r13)
688 lhi %r1,2094
689 lhi %r2,0
690 .long 0xb98e2001
691 oi 3(%r12),0x80 # set IDTE flag
692.Lchkidte:
693
694 lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space,
695 # virtual and never return ...
696 .align 8
697.Lentry:.long 0x00080000,0x80000000 + _stext
698.Lctl: .long 0x04b50002 # cr0: various things
699 .long 0 # cr1: primary space segment table
700 .long .Lduct # cr2: dispatchable unit control table
701 .long 0 # cr3: instruction authorization
702 .long 0 # cr4: instruction authorization
703 .long 0xffffffff # cr5: primary-aste origin
704 .long 0 # cr6: I/O interrupts
705 .long 0 # cr7: secondary space segment table
706 .long 0 # cr8: access registers translation
707 .long 0 # cr9: tracing off
708 .long 0 # cr10: tracing off
709 .long 0 # cr11: tracing off
710 .long 0 # cr12: tracing off
711 .long 0 # cr13: home space segment table
712 .long 0xc0000000 # cr14: machine check handling off
713 .long 0 # cr15: linkage stack operations
714.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
715.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
716.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
717.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
718.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
719.Lmemsize:.long memory_size
720.Lmchunk:.long memory_chunk
721.Lmflags:.long machine_flags
722.Lbss_bgn: .long __bss_start
723.Lbss_end: .long _end
724
725 .org PARMAREA-64
726.Lduct: .long 0,0,0,0,0,0,0,0
727 .long 0,0,0,0,0,0,0,0
728
729#
730# params at 10400 (setup.h)
731#
732 .org PARMAREA
733 .global _pstart
734_pstart:
735 .long 0,0 # IPL_DEVICE
736 .long 0,RAMDISK_ORIGIN # INITRD_START
737 .long 0,RAMDISK_SIZE # INITRD_SIZE
738
739 .org COMMAND_LINE
740 .byte "root=/dev/ram0 ro"
741 .byte 0
742 .org 0x11000
743.Lsccb:
744 .hword 0x1000 # length, one page
745 .byte 0x00,0x00,0x00
746 .byte 0x80 # variable response bit set
747.Lsccbr:
748 .hword 0x00 # response code
749.Lscpincr1:
750 .hword 0x00
751.Lscpa1:
752 .byte 0x00
753 .fill 89,1,0
754.Lscpa2:
755 .int 0x00
756.Lscpincr2:
757 .quad 0x00
758 .fill 3984,1,0
759 .org 0x12000
760 .global _pend
761_pend:
762
763.Lget_ipl_device: 484.Lget_ipl_device:
764 basr %r12,0 485 basr %r12,0
765.LPG2: l %r1,0xb8 # get sid 486.LGID: l %r1,0xb8 # get sid
766 sll %r1,15 # test if subchannel is enabled 487 sll %r1,15 # test if subchannel is enabled
767 srl %r1,31 488 srl %r1,31
768 ltr %r1,%r1 489 ltr %r1,%r1
769 bz 0(%r14) # subchannel disabled 490 bz 0(%r14) # subchannel disabled
770 l %r1,0xb8 491 l %r1,0xb8
771 la %r5,.Lipl_schib-.LPG2(%r12) 492 la %r5,.Lipl_schib-.LGID(%r12)
772 stsch 0(%r5) # get schib of subchannel 493 stsch 0(%r5) # get schib of subchannel
773 bnz 0(%r14) # schib not available 494 bnz 0(%r14) # schib not available
774 tm 5(%r5),0x01 # devno valid? 495 tm 5(%r5),0x01 # devno valid?
775 bno 0(%r14) 496 bno 0(%r14)
776 la %r6,ipl_parameter_flags-.LPG2(%r12) 497 la %r6,ipl_parameter_flags-.LGID(%r12)
777 oi 3(%r6),0x01 # set flag 498 oi 3(%r6),0x01 # set flag
778 la %r2,ipl_devno-.LPG2(%r12) 499 la %r2,ipl_devno-.LGID(%r12)
779 mvc 0(2,%r2),6(%r5) # store devno 500 mvc 0(2,%r2),6(%r5) # store devno
780 tm 4(%r5),0x80 # qdio capable device? 501 tm 4(%r5),0x80 # qdio capable device?
781 bno 0(%r14) 502 bno 0(%r14)
@@ -816,46 +537,10 @@ ipl_parameter_flags:
816 .globl ipl_devno 537 .globl ipl_devno
817ipl_devno: 538ipl_devno:
818 .word 0 539 .word 0
540.endm
819 541
820#ifdef CONFIG_SHARED_KERNEL 542#ifdef CONFIG_ARCH_S390X
821 .org 0x100000 543#include "head64.S"
544#else
545#include "head31.S"
822#endif 546#endif
823
824#
825# startup-code, running in virtual mode
826#
827 .globl _stext
828_stext: basr %r13,0 # get base
829.LPG3:
830#
831# Setup stack
832#
833 l %r15,.Linittu-.LPG3(%r13)
834 mvc __LC_CURRENT(4),__TI_task(%r15)
835 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
836 st %r15,__LC_KERNEL_STACK # set end of kernel stack
837 ahi %r15,-96
838 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
839
840# check control registers
841 stctl %c0,%c15,0(%r15)
842 oi 2(%r15),0x40 # enable sigp emergency signal
843 oi 0(%r15),0x10 # switch on low address protection
844 lctl %c0,%c15,0(%r15)
845
846#
847 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
848 l %r14,.Lstart-.LPG3(%r13)
849 basr %r14,%r14 # call start_kernel
850#
851# We returned from start_kernel ?!? PANIK
852#
853 basr %r13,0
854 lpsw .Ldw-.(%r13) # load disabled wait psw
855#
856 .align 8
857.Ldw: .long 0x000a0000,0x00000000
858.Linittu: .long init_thread_union
859.Lstart: .long start_kernel
860.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
861
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
new file mode 100644
index 000000000000..2d3b089bfb83
--- /dev/null
+++ b/arch/s390/kernel/head31.S
@@ -0,0 +1,336 @@
1/*
2 * arch/s390/kernel/head31.S
3 *
4 * (C) Copyright IBM Corp. 2005
5 *
6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * Rob van der Heij <rvdhei@iae.nl>
9 * Heiko Carstens <heiko.carstens@de.ibm.com>
10 *
11 */
12
13#
14# startup-code at 0x10000, running in absolute addressing mode
15# this is called either by the ipl loader or directly by PSW restart
16# or linload or SALIPL
17#
18 .org 0x10000
19startup:basr %r13,0 # get base
20.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13)
21 basr %r14, %r1
22 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
23 la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
24 # move IPL device to lowcore
25 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
26
27#
28# clear bss memory
29#
30 l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
31 l %r3,.Lbss_end-.LPG1(%r13) # end of bss
32 sr %r3,%r2 # length of bss
33 sr %r4,%r4
34 sr %r5,%r5 # set src,length and pad to zero
35 sr %r0,%r0
36 mvcle %r2,%r4,0 # clear mem
37 jo .-4 # branch back, if not finish
38
39 l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
40.Lservicecall:
41 stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
42
43 stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
44 la %r1,0x200 # set bit 22
45 o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
46 st %r1,.Lcr-.LPG1(%r13)
47 lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
48
49 mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
50 la %r1, .Lsclph-.LPG1(%r13)
51 a %r1,__LC_EXT_NEW_PSW+4 # set handler
52 st %r1,__LC_EXT_NEW_PSW+4
53
54 la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
55 la %r1, .Lsccb-PARMAREA(%r4) # our sccb
56 .insn rre,0xb2200000,%r2,%r1 # service call
57 ipm %r1
58 srl %r1,28 # get cc code
59 xr %r3, %r3
60 chi %r1,3
61 be .Lfchunk-.LPG1(%r13) # leave
62 chi %r1,2
63 be .Lservicecall-.LPG1(%r13)
64 lpsw .Lwaitsclp-.LPG1(%r13)
65.Lsclph:
66 lh %r1,.Lsccbr-PARMAREA(%r4)
67 chi %r1,0x10 # 0x0010 is the sucess code
68 je .Lprocsccb # let's process the sccb
69 chi %r1,0x1f0
70 bne .Lfchunk-.LPG1(%r13) # unhandled error code
71 c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced
72 bne .Lfchunk-.LPG1(%r13) # if no, give up
73 l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
74 b .Lservicecall-.LPG1(%r13)
75.Lprocsccb:
76 lhi %r1,0
77 icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
78 jnz .Lscnd
79 lhi %r1,0x800 # otherwise report 2GB
80.Lscnd:
81 lhi %r3,0x800 # limit reported memory size to 2GB
82 cr %r1,%r3
83 jl .Lno2gb
84 lr %r1,%r3
85.Lno2gb:
86 xr %r3,%r3 # same logic
87 ic %r3,.Lscpa1-PARMAREA(%r4)
88 chi %r3,0x00
89 jne .Lcompmem
90 l %r3,.Lscpa2-PARMAREA(%r13)
91.Lcompmem:
92 mr %r2,%r1 # mem in MB on 128-bit
93 l %r1,.Lonemb-.LPG1(%r13)
94 mr %r2,%r1 # mem size in bytes in %r3
95 b .Lfchunk-.LPG1(%r13)
96
97 .align 4
98.Lget_ipl_device_addr:
99 .long .Lget_ipl_device
100.Lpmask:
101 .byte 0
102.align 8
103.Lpcext:.long 0x00080000,0x80000000
104.Lcr:
105 .long 0x00 # place holder for cr0
106.Lwaitsclp:
107 .long 0x010a0000,0x80000000 + .Lsclph
108.Lrcp:
109 .int 0x00120001 # Read SCP forced code
110.Lrcp2:
111 .int 0x00020001 # Read SCP code
112.Lonemb:
113 .int 0x100000
114.Lfchunk:
115
116#
117# find memory chunks.
118#
119 lr %r9,%r3 # end of mem
120 mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
121 la %r1,1 # test in increments of 128KB
122 sll %r1,17
123 l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
124 slr %r4,%r4 # set start of chunk to zero
125 slr %r5,%r5 # set end of chunk to zero
126 slr %r6,%r6 # set access code to zero
127 la %r10, MEMORY_CHUNKS # number of chunks
128.Lloop:
129 tprot 0(%r5),0 # test protection of first byte
130 ipm %r7
131 srl %r7,28
132 clr %r6,%r7 # compare cc with last access code
133 be .Lsame-.LPG1(%r13)
134 b .Lchkmem-.LPG1(%r13)
135.Lsame:
136 ar %r5,%r1 # add 128KB to end of chunk
137 bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
138.Lchkmem: # > 2GB or tprot got a program check
139 clr %r4,%r5 # chunk size > 0?
140 be .Lchkloop-.LPG1(%r13)
141 st %r4,0(%r3) # store start address of chunk
142 lr %r0,%r5
143 slr %r0,%r4
144 st %r0,4(%r3) # store size of chunk
145 st %r6,8(%r3) # store type of chunk
146 la %r3,12(%r3)
147 l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
148 st %r5,0(%r4) # store last end to memory size
149 ahi %r10,-1 # update chunk number
150.Lchkloop:
151 lr %r6,%r7 # set access code to last cc
152 # we got an exception or we're starting a new
153 # chunk , we must check if we should
154 # still try to find valid memory (if we detected
155 # the amount of available storage), and if we
156 # have chunks left
157 xr %r0,%r0
158 clr %r0,%r9 # did we detect memory?
159 je .Ldonemem # if not, leave
160 chi %r10,0 # do we have chunks left?
161 je .Ldonemem
162 alr %r5,%r1 # add 128KB to end of chunk
163 lr %r4,%r5 # potential new chunk
164 clr %r5,%r9 # should we go on?
165 jl .Lloop
166.Ldonemem:
167 l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
168#
169# find out if we are running under VM
170#
171 stidp __LC_CPUID # store cpuid
172 tm __LC_CPUID,0xff # running under VM ?
173 bno .Lnovm-.LPG1(%r13)
174 oi 3(%r12),1 # set VM flag
175.Lnovm:
176 lh %r0,__LC_CPUID+4 # get cpu version
177 chi %r0,0x7490 # running on a P/390 ?
178 bne .Lnop390-.LPG1(%r13)
179 oi 3(%r12),4 # set P/390 flag
180.Lnop390:
181
182#
183# find out if we have an IEEE fpu
184#
185 mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
186 efpc %r0,0 # test IEEE extract fpc instruction
187 oi 3(%r12),2 # set IEEE fpu flag
188.Lchkfpu:
189
190#
191# find out if we have the CSP instruction
192#
193 mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
194 la %r0,0
195 lr %r1,%r0
196 la %r2,4
197 csp %r0,%r2 # Test CSP instruction
198 oi 3(%r12),8 # set CSP flag
199.Lchkcsp:
200
201#
202# find out if we have the MVPG instruction
203#
204 mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
205 sr %r0,%r0
206 la %r1,0
207 la %r2,0
208 mvpg %r1,%r2 # Test CSP instruction
209 oi 3(%r12),16 # set MVPG flag
210.Lchkmvpg:
211
212#
213# find out if we have the IDTE instruction
214#
215 mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
216 .long 0xb2b10000 # store facility list
217 tm 0xc8,0x08 # check bit for clearing-by-ASCE
218 bno .Lchkidte-.LPG1(%r13)
219 lhi %r1,2094
220 lhi %r2,0
221 .long 0xb98e2001
222 oi 3(%r12),0x80 # set IDTE flag
223.Lchkidte:
224
225 lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space,
226 # virtual and never return ...
227 .align 8
228.Lentry:.long 0x00080000,0x80000000 + _stext
229.Lctl: .long 0x04b50002 # cr0: various things
230 .long 0 # cr1: primary space segment table
231 .long .Lduct # cr2: dispatchable unit control table
232 .long 0 # cr3: instruction authorization
233 .long 0 # cr4: instruction authorization
234 .long 0xffffffff # cr5: primary-aste origin
235 .long 0 # cr6: I/O interrupts
236 .long 0 # cr7: secondary space segment table
237 .long 0 # cr8: access registers translation
238 .long 0 # cr9: tracing off
239 .long 0 # cr10: tracing off
240 .long 0 # cr11: tracing off
241 .long 0 # cr12: tracing off
242 .long 0 # cr13: home space segment table
243 .long 0xc0000000 # cr14: machine check handling off
244 .long 0 # cr15: linkage stack operations
245.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
246.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
247.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
248.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
249.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
250.Lmemsize:.long memory_size
251.Lmchunk:.long memory_chunk
252.Lmflags:.long machine_flags
253.Lbss_bgn: .long __bss_start
254.Lbss_end: .long _end
255
256 .org PARMAREA-64
257.Lduct: .long 0,0,0,0,0,0,0,0
258 .long 0,0,0,0,0,0,0,0
259
260#
261# params at 10400 (setup.h)
262#
263 .org PARMAREA
264 .global _pstart
265_pstart:
266 .long 0,0 # IPL_DEVICE
267 .long 0,RAMDISK_ORIGIN # INITRD_START
268 .long 0,RAMDISK_SIZE # INITRD_SIZE
269
270 .org COMMAND_LINE
271 .byte "root=/dev/ram0 ro"
272 .byte 0
273 .org 0x11000
274.Lsccb:
275 .hword 0x1000 # length, one page
276 .byte 0x00,0x00,0x00
277 .byte 0x80 # variable response bit set
278.Lsccbr:
279 .hword 0x00 # response code
280.Lscpincr1:
281 .hword 0x00
282.Lscpa1:
283 .byte 0x00
284 .fill 89,1,0
285.Lscpa2:
286 .int 0x00
287.Lscpincr2:
288 .quad 0x00
289 .fill 3984,1,0
290 .org 0x12000
291 .global _pend
292_pend:
293
294 GET_IPL_DEVICE
295
296#ifdef CONFIG_SHARED_KERNEL
297 .org 0x100000
298#endif
299
300#
301# startup-code, running in virtual mode
302#
303 .globl _stext
304_stext: basr %r13,0 # get base
305.LPG3:
306#
307# Setup stack
308#
309 l %r15,.Linittu-.LPG3(%r13)
310 mvc __LC_CURRENT(4),__TI_task(%r15)
311 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
312 st %r15,__LC_KERNEL_STACK # set end of kernel stack
313 ahi %r15,-96
314 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
315
316# check control registers
317 stctl %c0,%c15,0(%r15)
318 oi 2(%r15),0x40 # enable sigp emergency signal
319 oi 0(%r15),0x10 # switch on low address protection
320 lctl %c0,%c15,0(%r15)
321
322#
323 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
324 l %r14,.Lstart-.LPG3(%r13)
325 basr %r14,%r14 # call start_kernel
326#
327# We returned from start_kernel ?!? PANIK
328#
329 basr %r13,0
330 lpsw .Ldw-.(%r13) # load disabled wait psw
331#
332 .align 8
333.Ldw: .long 0x000a0000,0x00000000
334.Linittu:.long init_thread_union
335.Lstart:.long start_kernel
336.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 193aafa72f54..f08c06f45d5c 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -1,482 +1,17 @@
1/* 1/*
2 * arch/s390/kernel/head.S 2 * arch/s390/kernel/head64.S
3 * 3 *
4 * S390 version 4 * (C) Copyright IBM Corp. 1999,2005
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
6 * Author(s): Hartmut Penner (hp@de.ibm.com), 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky (schwidefsky@de.ibm.com), 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * Rob van der Heij (rvdhei@iae.nl) 8 * Rob van der Heij <rvdhei@iae.nl>
9 * Heiko Carstens <heiko.carstens@de.ibm.com>
9 * 10 *
10 * There are 5 different IPL methods
11 * 1) load the image directly into ram at address 0 and do an PSW restart
12 * 2) linload will load the image from address 0x10000 to memory 0x10000
13 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
14 * 3) generate the tape ipl header, store the generated image on a tape
15 * and ipl from it
16 * In case of SL tape you need to IPL 5 times to get past VOL1 etc
17 * 4) generate the vm reader ipl header, move the generated image to the
18 * VM reader (use option NOH!) and do a ipl from reader (VM only)
19 * 5) direct call of start by the SALIPL loader
20 * We use the cpuid to distinguish between VM and native ipl
21 * params for kernel are pushed to 0x10400 (see setup.h)
22
23 Changes:
24 Okt 25 2000 <rvdheij@iae.nl>
25 added code to skip HDR and EOF to allow SL tape IPL (5 retries)
26 changed first CCW from rewind to backspace block
27
28 */ 11 */
29 12
30#include <linux/config.h>
31#include <asm/setup.h>
32#include <asm/lowcore.h>
33#include <asm/asm-offsets.h>
34#include <asm/thread_info.h>
35#include <asm/page.h>
36
37#ifndef CONFIG_IPL
38 .org 0
39 .long 0x00080000,0x80000000+startup # Just a restart PSW
40#else
41#ifdef CONFIG_IPL_TAPE
42#define IPL_BS 1024
43 .org 0
44 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
45 .long 0x27000000,0x60000001 # by ipl to addresses 0-23.
46 .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs).
47 .long 0x00000000,0x00000000 # external old psw
48 .long 0x00000000,0x00000000 # svc old psw
49 .long 0x00000000,0x00000000 # program check old psw
50 .long 0x00000000,0x00000000 # machine check old psw
51 .long 0x00000000,0x00000000 # io old psw
52 .long 0x00000000,0x00000000
53 .long 0x00000000,0x00000000
54 .long 0x00000000,0x00000000
55 .long 0x000a0000,0x00000058 # external new psw
56 .long 0x000a0000,0x00000060 # svc new psw
57 .long 0x000a0000,0x00000068 # program check new psw
58 .long 0x000a0000,0x00000070 # machine check new psw
59 .long 0x00080000,0x80000000+.Lioint # io new psw
60
61 .org 0x100
62#
63# subroutine for loading from tape
64# Paramters:
65# R1 = device number
66# R2 = load address
67.Lloader:
68 st %r14,.Lldret
69 la %r3,.Lorbread # r3 = address of orb
70 la %r5,.Lirb # r5 = address of irb
71 st %r2,.Lccwread+4 # initialize CCW data addresses
72 lctl %c6,%c6,.Lcr6
73 slr %r2,%r2
74.Lldlp:
75 la %r6,3 # 3 retries
76.Lssch:
77 ssch 0(%r3) # load chunk of IPL_BS bytes
78 bnz .Llderr
79.Lw4end:
80 bas %r14,.Lwait4io
81 tm 8(%r5),0x82 # do we have a problem ?
82 bnz .Lrecov
83 slr %r7,%r7
84 icm %r7,3,10(%r5) # get residual count
85 lcr %r7,%r7
86 la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read
87 ar %r2,%r7 # add to total size
88 tm 8(%r5),0x01 # found a tape mark ?
89 bnz .Ldone
90 l %r0,.Lccwread+4 # update CCW data addresses
91 ar %r0,%r7
92 st %r0,.Lccwread+4
93 b .Lldlp
94.Ldone:
95 l %r14,.Lldret
96 br %r14 # r2 contains the total size
97.Lrecov:
98 bas %r14,.Lsense # do the sensing
99 bct %r6,.Lssch # dec. retry count & branch
100 b .Llderr
101#
102# Sense subroutine
103#
104.Lsense:
105 st %r14,.Lsnsret
106 la %r7,.Lorbsense
107 ssch 0(%r7) # start sense command
108 bnz .Llderr
109 bas %r14,.Lwait4io
110 l %r14,.Lsnsret
111 tm 8(%r5),0x82 # do we have a problem ?
112 bnz .Llderr
113 br %r14
114#
115# Wait for interrupt subroutine
116#
117.Lwait4io:
118 lpsw .Lwaitpsw
119.Lioint:
120 c %r1,0xb8 # compare subchannel number
121 bne .Lwait4io
122 tsch 0(%r5)
123 slr %r0,%r0
124 tm 8(%r5),0x82 # do we have a problem ?
125 bnz .Lwtexit
126 tm 8(%r5),0x04 # got device end ?
127 bz .Lwait4io
128.Lwtexit:
129 br %r14
130.Llderr:
131 lpsw .Lcrash
132
133 .align 8
134.Lorbread:
135 .long 0x00000000,0x0080ff00,.Lccwread
136 .align 8
137.Lorbsense:
138 .long 0x00000000,0x0080ff00,.Lccwsense
139 .align 8
140.Lccwread:
141 .long 0x02200000+IPL_BS,0x00000000
142.Lccwsense:
143 .long 0x04200001,0x00000000
144.Lwaitpsw:
145 .long 0x020a0000,0x80000000+.Lioint
146
147.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
148.Lcr6: .long 0xff000000
149 .align 8
150.Lcrash:.long 0x000a0000,0x00000000
151.Lldret:.long 0
152.Lsnsret: .long 0
153#endif /* CONFIG_IPL_TAPE */
154
155#ifdef CONFIG_IPL_VM
156#define IPL_BS 0x730
157 .org 0
158 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
159 .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
160 .long 0x02000068,0x60000050 # (a PSW and two CCWs).
161 .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
162 .long 0x020000f0,0x60000050 # The next 160 byte are loaded
163 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
164 .long 0x02000190,0x60000050 # They form the continuation
165 .long 0x020001e0,0x60000050 # of the CCW program started
166 .long 0x02000230,0x60000050 # by ipl and load the range
167 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
168 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
169 .long 0x02000320,0x60000050 # in memory. At the end of
170 .long 0x02000370,0x60000050 # the channel program the PSW
171 .long 0x020003c0,0x60000050 # at location 0 is loaded.
172 .long 0x02000410,0x60000050 # Initial processing starts
173 .long 0x02000460,0x60000050 # at 0xf0 = iplstart.
174 .long 0x020004b0,0x60000050
175 .long 0x02000500,0x60000050
176 .long 0x02000550,0x60000050
177 .long 0x020005a0,0x60000050
178 .long 0x020005f0,0x60000050
179 .long 0x02000640,0x60000050
180 .long 0x02000690,0x60000050
181 .long 0x020006e0,0x20000050
182
183 .org 0xf0
184#
185# subroutine for loading cards from the reader
186#
187.Lloader:
188 la %r3,.Lorb # r2 = address of orb into r2
189 la %r5,.Lirb # r4 = address of irb
190 la %r6,.Lccws
191 la %r7,20
192.Linit:
193 st %r2,4(%r6) # initialize CCW data addresses
194 la %r2,0x50(%r2)
195 la %r6,8(%r6)
196 bct 7,.Linit
197
198 lctl %c6,%c6,.Lcr6 # set IO subclass mask
199 slr %r2,%r2
200.Lldlp:
201 ssch 0(%r3) # load chunk of 1600 bytes
202 bnz .Llderr
203.Lwait4irq:
204 mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
205 lpsw .Lwaitpsw
206.Lioint:
207 c %r1,0xb8 # compare subchannel number
208 bne .Lwait4irq
209 tsch 0(%r5)
210
211 slr %r0,%r0
212 ic %r0,8(%r5) # get device status
213 chi %r0,8 # channel end ?
214 be .Lcont
215 chi %r0,12 # channel end + device end ?
216 be .Lcont
217
218 l %r0,4(%r5)
219 s %r0,8(%r3) # r0/8 = number of ccws executed
220 mhi %r0,10 # *10 = number of bytes in ccws
221 lh %r3,10(%r5) # get residual count
222 sr %r0,%r3 # #ccws*80-residual=#bytes read
223 ar %r2,%r0
224
225 br %r14 # r2 contains the total size
226
227.Lcont:
228 ahi %r2,0x640 # add 0x640 to total size
229 la %r6,.Lccws
230 la %r7,20
231.Lincr:
232 l %r0,4(%r6) # update CCW data addresses
233 ahi %r0,0x640
234 st %r0,4(%r6)
235 ahi %r6,8
236 bct 7,.Lincr
237
238 b .Lldlp
239.Llderr:
240 lpsw .Lcrash
241
242 .align 8
243.Lorb: .long 0x00000000,0x0080ff00,.Lccws
244.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
245.Lcr6: .long 0xff000000
246.Lloadp:.long 0,0
247 .align 8
248.Lcrash:.long 0x000a0000,0x00000000
249.Lnewpsw:
250 .long 0x00080000,0x80000000+.Lioint
251.Lwaitpsw:
252 .long 0x020a0000,0x80000000+.Lioint
253
254 .align 8
255.Lccws: .rept 19
256 .long 0x02600050,0x00000000
257 .endr
258 .long 0x02200050,0x00000000
259#endif /* CONFIG_IPL_VM */
260
261iplstart:
262 lh %r1,0xb8 # test if subchannel number
263 bct %r1,.Lnoload # is valid
264 l %r1,0xb8 # load ipl subchannel number
265 la %r2,IPL_BS # load start address
266 bas %r14,.Lloader # load rest of ipl image
267 larl %r12,_pstart # pointer to parameter area
268 st %r1,IPL_DEVICE+4-PARMAREA(%r12) # store ipl device number
269
270#
271# load parameter file from ipl device
272# 13#
273.Lagain1: 14# startup-code at 0x10000, running in absolute addressing mode
274 l %r2,INITRD_START+4-PARMAREA(%r12)# use ramdisk location as temp
275 bas %r14,.Lloader # load parameter file
276 ltr %r2,%r2 # got anything ?
277 bz .Lnopf
278 chi %r2,895
279 bnh .Lnotrunc
280 la %r2,895
281.Lnotrunc:
282 l %r4,INITRD_START+4-PARMAREA(%r12)
283 clc 0(3,%r4),.L_hdr # if it is HDRx
284 bz .Lagain1 # skip dataset header
285 clc 0(3,%r4),.L_eof # if it is EOFx
286 bz .Lagain1 # skip dateset trailer
287 la %r5,0(%r4,%r2)
288 lr %r3,%r2
289.Lidebc:
290 tm 0(%r5),0x80 # high order bit set ?
291 bo .Ldocv # yes -> convert from EBCDIC
292 ahi %r5,-1
293 bct %r3,.Lidebc
294 b .Lnocv
295.Ldocv:
296 l %r3,.Lcvtab
297 tr 0(256,%r4),0(%r3) # convert parameters to ascii
298 tr 256(256,%r4),0(%r3)
299 tr 512(256,%r4),0(%r3)
300 tr 768(122,%r4),0(%r3)
301.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
302 mvc 0(256,%r3),0(%r4)
303 mvc 256(256,%r3),256(%r4)
304 mvc 512(256,%r3),512(%r4)
305 mvc 768(122,%r3),768(%r4)
306 slr %r0,%r0
307 b .Lcntlp
308.Ldelspc:
309 ic %r0,0(%r2,%r3)
310 chi %r0,0x20 # is it a space ?
311 be .Lcntlp
312 ahi %r2,1
313 b .Leolp
314.Lcntlp:
315 brct %r2,.Ldelspc
316.Leolp:
317 slr %r0,%r0
318 stc %r0,0(%r2,%r3) # terminate buffer
319.Lnopf:
320
321#
322# load ramdisk from ipl device
323#
324.Lagain2:
325 l %r2,INITRD_START+4-PARMAREA(%r12)# load adr. of ramdisk
326 bas %r14,.Lloader # load ramdisk
327 st %r2,INITRD_SIZE+4-PARMAREA(%r12) # store size of ramdisk
328 ltr %r2,%r2
329 bnz .Lrdcont
330 st %r2,INITRD_START+4-PARMAREA(%r12)# no ramdisk found, null it
331.Lrdcont:
332 l %r2,INITRD_START+4-PARMAREA(%r12)
333 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
334 bz .Lagain2
335 clc 0(3,%r2),.L_eof
336 bz .Lagain2
337
338#ifdef CONFIG_IPL_VM
339#
340# reset files in VM reader
341#
342 stidp __LC_CPUID # store cpuid
343 tm __LC_CPUID,0xff # running VM ?
344 bno .Lnoreset
345 la %r2,.Lreset
346 lhi %r3,26
347 diag %r2,%r3,8
348 la %r5,.Lirb
349 stsch 0(%r5) # check if irq is pending
350 tm 30(%r5),0x0f # by verifying if any of the
351 bnz .Lwaitforirq # activity or status control
352 tm 31(%r5),0xff # bits is set in the schib
353 bz .Lnoreset
354.Lwaitforirq:
355 mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
356.Lwaitrdrirq:
357 lpsw .Lrdrwaitpsw
358.Lrdrint:
359 c %r1,0xb8 # compare subchannel number
360 bne .Lwaitrdrirq
361 la %r5,.Lirb
362 tsch 0(%r5)
363.Lnoreset:
364 b .Lnoload
365
366 .align 8
367.Lrdrnewpsw:
368 .long 0x00080000,0x80000000+.Lrdrint
369.Lrdrwaitpsw:
370 .long 0x020a0000,0x80000000+.Lrdrint
371#endif
372
373#
374# everything loaded, go for it
375#
376.Lnoload:
377 l %r1,.Lstartup
378 br %r1
379
380.Lstartup: .long startup
381.Lcvtab:.long _ebcasc # ebcdic to ascii table
382.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
383 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
384 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
385.L_eof: .long 0xc5d6c600 /* C'EOF' */
386.L_hdr: .long 0xc8c4d900 /* C'HDR' */
387#endif /* CONFIG_IPL */
388
389#
390# SALIPL loader support. Based on a patch by Rob van der Heij.
391# This entry point is called directly from the SALIPL loader and
392# doesn't need a builtin ipl record.
393#
394 .org 0x800
395 .globl start
396start:
397 stm %r0,%r15,0x07b0 # store registers
398 basr %r12,%r0
399.base:
400 l %r11,.parm
401 l %r8,.cmd # pointer to command buffer
402
403 ltr %r9,%r9 # do we have SALIPL parameters?
404 bp .sk8x8
405
406 mvc 0(64,%r8),0x00b0 # copy saved registers
407 xc 64(240-64,%r8),0(%r8) # remainder of buffer
408 tr 0(64,%r8),.lowcase
409 b .gotr
410.sk8x8:
411 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
412.gotr:
413 l %r10,.tbl # EBCDIC to ASCII table
414 tr 0(240,%r8),0(%r10)
415 stidp __LC_CPUID # Are we running on VM maybe
416 cli __LC_CPUID,0xff
417 bnz .test
418 .long 0x83300060 # diag 3,0,x'0060' - storage size
419 b .done
420.test:
421 mvc 0x68(8),.pgmnw # set up pgm check handler
422 l %r2,.fourmeg
423 lr %r3,%r2
424 bctr %r3,%r0 # 4M-1
425.loop: iske %r0,%r3
426 ar %r3,%r2
427.pgmx:
428 sr %r3,%r2
429 la %r3,1(%r3)
430.done:
431 l %r1,.memsize
432 st %r3,4(%r1)
433 slr %r0,%r0
434 st %r0,INITRD_SIZE+4-PARMAREA(%r11)
435 st %r0,INITRD_START+4-PARMAREA(%r11)
436 j startup # continue with startup
437.tbl: .long _ebcasc # translate table
438.cmd: .long COMMAND_LINE # address of command line buffer
439.parm: .long PARMAREA
440.fourmeg: .long 0x00400000 # 4M
441.pgmnw: .long 0x00080000,.pgmx
442.memsize: .long memory_size
443.lowcase:
444 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
445 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
446 .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
447 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
448 .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
449 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
450 .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
451 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
452 .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
453 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
454 .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
455 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
456 .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
457 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
458 .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
459 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
460
461 .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
462 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
463 .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
464 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
465 .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
466 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
467 .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
468 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
469 .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
470 .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
471 .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
472 .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr
473 .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx
474 .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz
475 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
476 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
477
478#
479# startup-code at 0x10000, running in real mode
480# this is called either by the ipl loader or directly by PSW restart 15# this is called either by the ipl loader or directly by PSW restart
481# or linload or SALIPL 16# or linload or SALIPL
482# 17#
@@ -530,7 +65,7 @@ startup:basr %r13,0 # get base
530 be .Lfchunk-.LPG1(%r13) # leave 65 be .Lfchunk-.LPG1(%r13) # leave
531 chi %r1,2 66 chi %r1,2
532 be .Lservicecall-.LPG1(%r13) 67 be .Lservicecall-.LPG1(%r13)
533 lpsw .Lwaitsclp-.LPG1(%r13) 68 lpswe .Lwaitsclp-.LPG1(%r13)
534.Lsclph: 69.Lsclph:
535 lh %r1,.Lsccbr-PARMAREA(%r4) 70 lh %r1,.Lsccbr-PARMAREA(%r4)
536 chi %r1,0x10 # 0x0010 is the sucess code 71 chi %r1,0x10 # 0x0010 is the sucess code
@@ -567,8 +102,7 @@ startup:basr %r13,0 # get base
567.Lcr: 102.Lcr:
568 .quad 0x00 # place holder for cr0 103 .quad 0x00 # place holder for cr0
569.Lwaitsclp: 104.Lwaitsclp:
570 .long 0x020A0000 105 .quad 0x0102000180000000,.Lsclph
571 .quad .Lsclph
572.Lrcp: 106.Lrcp:
573 .int 0x00120001 # Read SCP forced code 107 .int 0x00120001 # Read SCP forced code
574.Lrcp2: 108.Lrcp2:
@@ -751,62 +285,7 @@ _pstart:
751 .global _pend 285 .global _pend
752_pend: 286_pend:
753 287
754.Lget_ipl_device: 288 GET_IPL_DEVICE
755 basr %r12,0
756.LPG2: l %r1,0xb8 # get sid
757 sll %r1,15 # test if subchannel is enabled
758 srl %r1,31
759 ltr %r1,%r1
760 bz 0(%r14) # subchannel disabled
761 l %r1,0xb8
762 la %r5,.Lipl_schib-.LPG2(%r12)
763 stsch 0(%r5) # get schib of subchannel
764 bnz 0(%r14) # schib not available
765 tm 5(%r5),0x01 # devno valid?
766 bno 0(%r14)
767 la %r6,ipl_parameter_flags-.LPG2(%r12)
768 oi 3(%r6),0x01 # set flag
769 la %r2,ipl_devno-.LPG2(%r12)
770 mvc 0(2,%r2),6(%r5) # store devno
771 tm 4(%r5),0x80 # qdio capable device?
772 bno 0(%r14)
773 oi 3(%r6),0x02 # set flag
774
775 # copy ipl parameters
776
777 lhi %r0,4096
778 l %r2,20(%r0) # get address of parameter list
779 lhi %r3,IPL_PARMBLOCK_ORIGIN
780 st %r3,20(%r0)
781 lhi %r4,1
782 cr %r2,%r3 # start parameters < destination ?
783 jl 0f
784 lhi %r1,1 # copy direction is upwards
785 j 1f
7860: lhi %r1,-1 # copy direction is downwards
787 ar %r2,%r0
788 ar %r3,%r0
789 ar %r2,%r1
790 ar %r3,%r1
7911: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
792 ar %r3,%r1
793 ar %r2,%r1
794 sr %r0,%r4
795 jne 1b
796 b 0(%r14)
797
798 .align 4
799.Lipl_schib:
800 .rept 13
801 .long 0
802 .endr
803
804 .globl ipl_parameter_flags
805ipl_parameter_flags:
806 .long 0
807 .globl ipl_devno
808ipl_devno:
809 .word 0
810 289
811#ifdef CONFIG_SHARED_KERNEL 290#ifdef CONFIG_SHARED_KERNEL
812 .org 0x100000 291 .org 0x100000
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 9a1d95894f3d..c36353e8c140 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -237,6 +237,8 @@ int sysctl_hz_timer = 1;
237 */ 237 */
238static inline void stop_hz_timer(void) 238static inline void stop_hz_timer(void)
239{ 239{
240 unsigned long flags;
241 unsigned long seq, next;
240 __u64 timer, todval; 242 __u64 timer, todval;
241 243
242 if (sysctl_hz_timer != 0) 244 if (sysctl_hz_timer != 0)
@@ -257,7 +259,11 @@ static inline void stop_hz_timer(void)
257 * This cpu is going really idle. Set up the clock comparator 259 * This cpu is going really idle. Set up the clock comparator
258 * for the next event. 260 * for the next event.
259 */ 261 */
260 timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; 262 next = next_timer_interrupt();
263 do {
264 seq = read_seqbegin_irqsave(&xtime_lock, flags);
265 timer = (__u64)(next - jiffies) + jiffies_64;
266 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
261 todval = -1ULL; 267 todval = -1ULL;
262 /* Be careful about overflows. */ 268 /* Be careful about overflows. */
263 if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { 269 if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 6b8703ec2ae6..c5bd36fae56b 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -57,7 +57,6 @@ int sysctl_userprocess_debug = 0;
57 57
58extern pgm_check_handler_t do_protection_exception; 58extern pgm_check_handler_t do_protection_exception;
59extern pgm_check_handler_t do_dat_exception; 59extern pgm_check_handler_t do_dat_exception;
60extern pgm_check_handler_t do_pseudo_page_fault;
61#ifdef CONFIG_PFAULT 60#ifdef CONFIG_PFAULT
62extern int pfault_init(void); 61extern int pfault_init(void);
63extern void pfault_fini(void); 62extern void pfault_fini(void);
@@ -676,20 +675,6 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
676 panic("Corrupt kernel stack, can't continue."); 675 panic("Corrupt kernel stack, can't continue.");
677} 676}
678 677
679#ifndef CONFIG_ARCH_S390X
680static int
681pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
682{
683 if (MACHINE_IS_VM)
684 cpcmd("SET PAGEX OFF", NULL, 0, NULL);
685 return NOTIFY_DONE;
686}
687
688static struct notifier_block pagex_reboot_notifier = {
689 .notifier_call = &pagex_reboot_event,
690};
691#endif
692
693/* init is done in lowcore.S and head.S */ 678/* init is done in lowcore.S and head.S */
694 679
695void __init trap_init(void) 680void __init trap_init(void)
@@ -717,9 +702,7 @@ void __init trap_init(void)
717 pgm_check_table[0x11] = &do_dat_exception; 702 pgm_check_table[0x11] = &do_dat_exception;
718 pgm_check_table[0x12] = &translation_exception; 703 pgm_check_table[0x12] = &translation_exception;
719 pgm_check_table[0x13] = &special_op_exception; 704 pgm_check_table[0x13] = &special_op_exception;
720#ifndef CONFIG_ARCH_S390X 705#ifdef CONFIG_ARCH_S390X
721 pgm_check_table[0x14] = &do_pseudo_page_fault;
722#else /* CONFIG_ARCH_S390X */
723 pgm_check_table[0x38] = &do_dat_exception; 706 pgm_check_table[0x38] = &do_dat_exception;
724 pgm_check_table[0x39] = &do_dat_exception; 707 pgm_check_table[0x39] = &do_dat_exception;
725 pgm_check_table[0x3A] = &do_dat_exception; 708 pgm_check_table[0x3A] = &do_dat_exception;
@@ -731,12 +714,10 @@ void __init trap_init(void)
731 pgm_check_table[0x40] = &do_monitor_call; 714 pgm_check_table[0x40] = &do_monitor_call;
732 715
733 if (MACHINE_IS_VM) { 716 if (MACHINE_IS_VM) {
717#ifdef CONFIG_PFAULT
734 /* 718 /*
735 * First try to get pfault pseudo page faults going. 719 * Try to get pfault pseudo page faults going.
736 * If this isn't available turn on pagex page faults.
737 */ 720 */
738#ifdef CONFIG_PFAULT
739 /* request the 0x2603 external interrupt */
740 if (register_early_external_interrupt(0x2603, pfault_interrupt, 721 if (register_early_external_interrupt(0x2603, pfault_interrupt,
741 &ext_int_pfault) != 0) 722 &ext_int_pfault) != 0)
742 panic("Couldn't request external interrupt 0x2603"); 723 panic("Couldn't request external interrupt 0x2603");
@@ -748,9 +729,5 @@ void __init trap_init(void)
748 unregister_early_external_interrupt(0x2603, pfault_interrupt, 729 unregister_early_external_interrupt(0x2603, pfault_interrupt,
749 &ext_int_pfault); 730 &ext_int_pfault);
750#endif 731#endif
751#ifndef CONFIG_ARCH_S390X
752 register_reboot_notifier(&pagex_reboot_notifier);
753 cpcmd("SET PAGEX ON", NULL, 0, NULL);
754#endif
755 } 732 }
756} 733}
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index c5348108ca3c..506a33b51e4f 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -234,8 +234,8 @@ query_segment_type (struct dcss_segment *seg)
234 rc = 0; 234 rc = 0;
235 235
236 out_free: 236 out_free:
237 if (qin) kfree(qin); 237 kfree(qin);
238 if (qout) kfree(qout); 238 kfree(qout);
239 return rc; 239 return rc;
240} 240}
241 241
@@ -394,7 +394,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
394 segtype_string[seg->vm_segtype]); 394 segtype_string[seg->vm_segtype]);
395 goto out; 395 goto out;
396 out_free: 396 out_free:
397 kfree (seg); 397 kfree(seg);
398 out: 398 out:
399 return rc; 399 return rc;
400} 400}
@@ -505,7 +505,7 @@ segment_modify_shared (char *name, int do_nonshared)
505 list_del(&seg->list); 505 list_del(&seg->list);
506 dcss_diag(DCSS_PURGESEG, seg->dcss_name, 506 dcss_diag(DCSS_PURGESEG, seg->dcss_name,
507 &dummy, &dummy); 507 &dummy, &dummy);
508 kfree (seg); 508 kfree(seg);
509 out_unlock: 509 out_unlock:
510 spin_unlock(&dcss_lock); 510 spin_unlock(&dcss_lock);
511 return rc; 511 return rc;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 856a971759b1..64e32da77754 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -352,115 +352,6 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code)
352 do_exception(regs, error_code & 0xff, 0); 352 do_exception(regs, error_code & 0xff, 0);
353} 353}
354 354
355#ifndef CONFIG_ARCH_S390X
356
357typedef struct _pseudo_wait_t {
358 struct _pseudo_wait_t *next;
359 wait_queue_head_t queue;
360 unsigned long address;
361 int resolved;
362} pseudo_wait_t;
363
364static pseudo_wait_t *pseudo_lock_queue = NULL;
365static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
366
367/*
368 * This routine handles 'pagex' pseudo page faults.
369 */
370asmlinkage void
371do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
372{
373 pseudo_wait_t wait_struct;
374 pseudo_wait_t *ptr, *last, *next;
375 unsigned long address;
376
377 /*
378 * get the failing address
379 * more specific the segment and page table portion of
380 * the address
381 */
382 address = S390_lowcore.trans_exc_code & 0xfffff000;
383
384 if (address & 0x80000000) {
385 /* high bit set -> a page has been swapped in by VM */
386 address &= 0x7fffffff;
387 spin_lock(&pseudo_wait_spinlock);
388 last = NULL;
389 ptr = pseudo_lock_queue;
390 while (ptr != NULL) {
391 next = ptr->next;
392 if (address == ptr->address) {
393 /*
394 * This is one of the processes waiting
395 * for the page. Unchain from the queue.
396 * There can be more than one process
397 * waiting for the same page. VM presents
398 * an initial and a completion interrupt for
399 * every process that tries to access a
400 * page swapped out by VM.
401 */
402 if (last == NULL)
403 pseudo_lock_queue = next;
404 else
405 last->next = next;
406 /* now wake up the process */
407 ptr->resolved = 1;
408 wake_up(&ptr->queue);
409 } else
410 last = ptr;
411 ptr = next;
412 }
413 spin_unlock(&pseudo_wait_spinlock);
414 } else {
415 /* Pseudo page faults in kernel mode is a bad idea */
416 if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
417 /*
418 * VM presents pseudo page faults if the interrupted
419 * state was not disabled for interrupts. So we can
420 * get pseudo page fault interrupts while running
421 * in kernel mode. We simply access the page here
422 * while we are running disabled. VM will then swap
423 * in the page synchronously.
424 */
425 if (check_user_space(regs, error_code) == 0)
426 /* dereference a virtual kernel address */
427 __asm__ __volatile__ (
428 " ic 0,0(%0)"
429 : : "a" (address) : "0");
430 else
431 /* dereference a virtual user address */
432 __asm__ __volatile__ (
433 " la 2,0(%0)\n"
434 " sacf 512\n"
435 " ic 2,0(2)\n"
436 "0:sacf 0\n"
437 ".section __ex_table,\"a\"\n"
438 " .align 4\n"
439 " .long 0b,0b\n"
440 ".previous"
441 : : "a" (address) : "2" );
442
443 return;
444 }
445 /* initialize and add element to pseudo_lock_queue */
446 init_waitqueue_head (&wait_struct.queue);
447 wait_struct.address = address;
448 wait_struct.resolved = 0;
449 spin_lock(&pseudo_wait_spinlock);
450 wait_struct.next = pseudo_lock_queue;
451 pseudo_lock_queue = &wait_struct;
452 spin_unlock(&pseudo_wait_spinlock);
453 /*
454 * The instruction that caused the program check will
455 * be repeated. Don't signal single step via SIGTRAP.
456 */
457 clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
458 /* go to sleep */
459 wait_event(wait_struct.queue, wait_struct.resolved);
460 }
461}
462#endif /* CONFIG_ARCH_S390X */
463
464#ifdef CONFIG_PFAULT 355#ifdef CONFIG_PFAULT
465/* 356/*
466 * 'pfault' pseudo page faults routines. 357 * 'pfault' pseudo page faults routines.
@@ -508,7 +399,7 @@ int pfault_init(void)
508 " .quad 0b,1b\n" 399 " .quad 0b,1b\n"
509#endif /* CONFIG_ARCH_S390X */ 400#endif /* CONFIG_ARCH_S390X */
510 ".previous" 401 ".previous"
511 : "=d" (rc) : "a" (&refbk) : "cc" ); 402 : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
512 __ctl_set_bit(0, 9); 403 __ctl_set_bit(0, 9);
513 return rc; 404 return rc;
514} 405}
@@ -532,7 +423,7 @@ void pfault_fini(void)
532 " .quad 0b,0b\n" 423 " .quad 0b,0b\n"
533#endif /* CONFIG_ARCH_S390X */ 424#endif /* CONFIG_ARCH_S390X */
534 ".previous" 425 ".previous"
535 : : "a" (&refbk) : "cc" ); 426 : : "a" (&refbk), "m" (refbk) : "cc" );
536} 427}
537 428
538asmlinkage void 429asmlinkage void
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 3e804c736e64..64f5ae0ff96d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -490,16 +490,6 @@ config CPU_SUBTYPE_ST40
490 depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 490 depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
491 default y 491 default y
492 492
493config ARCH_DISCONTIGMEM_ENABLE
494 bool
495 depends on SH_HP690
496 default y
497 help
498 Say Y to upport efficient handling of discontiguous physical memory,
499 for architectures which are either NUMA (Non-Uniform Memory Access)
500 or have huge holes in the physical address space for other reasons.
501 See <file:Documentation/vm/numa> for more.
502
503source "mm/Kconfig" 493source "mm/Kconfig"
504 494
505config ZERO_PAGE_OFFSET 495config ZERO_PAGE_OFFSET
@@ -770,24 +760,6 @@ source "fs/Kconfig.binfmt"
770 760
771endmenu 761endmenu
772 762
773menu "SH initrd options"
774 depends on BLK_DEV_INITRD
775
776config EMBEDDED_RAMDISK
777 bool "Embed root filesystem ramdisk into the kernel"
778
779config EMBEDDED_RAMDISK_IMAGE
780 string "Filename of gziped ramdisk image"
781 depends on EMBEDDED_RAMDISK
782 default "ramdisk.gz"
783 help
784 This is the filename of the ramdisk image to be built into the
785 kernel. Relative pathnames are relative to arch/sh/ramdisk/.
786 The ramdisk image is not part of the kernel distribution; you must
787 provide one yourself.
788
789endmenu
790
791source "net/Kconfig" 763source "net/Kconfig"
792 764
793source "drivers/Kconfig" 765source "drivers/Kconfig"
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 4a3049080b41..67192d6b00d8 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -60,14 +60,6 @@ LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
60 60
61core-y += arch/sh/kernel/ arch/sh/mm/ 61core-y += arch/sh/kernel/ arch/sh/mm/
62 62
63#
64# ramdisk/initrd support
65# You need a compressed ramdisk image, named
66# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames
67# are relative to arch/sh/ramdisk/.
68#
69core-$(CONFIG_EMBEDDED_RAMDISK) += arch/sh/ramdisk/
70
71# Boards 63# Boards
72machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x 64machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
73machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 65machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index bd6726cde398..338c3729d270 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the Linux SuperH-specific device drivers. 2# Makefile for the Linux SuperH-specific device drivers.
3# 3#
4 4
5obj-$(CONFIG_PCI) += pci/ 5obj-$(CONFIG_PCI) += pci/
6obj-$(CONFIG_SH_DMA) += dma/ 6obj-$(CONFIG_SH_DMA) += dma/
7obj-$(CONFIG_SUPERHYWAY) += superhyway/
7 8
diff --git a/arch/sh/drivers/superhyway/Makefile b/arch/sh/drivers/superhyway/Makefile
new file mode 100644
index 000000000000..5b8e0c7ca3a5
--- /dev/null
+++ b/arch/sh/drivers/superhyway/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the SuperHyway specific kernel interface routines under Linux.
3#
4
5obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += ops-sh4-202.o
6
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
new file mode 100644
index 000000000000..a55c98a9052b
--- /dev/null
+++ b/arch/sh/drivers/superhyway/ops-sh4-202.c
@@ -0,0 +1,171 @@
1/*
2 * arch/sh/drivers/superhyway/ops-sh4-202.c
3 *
4 * SuperHyway bus support for SH4-202
5 *
6 * Copyright (C) 2005 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU
9 * General Public License. See the file "COPYING" in the main
10 * directory of this archive for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/superhyway.h>
15#include <linux/string.h>
16#include <asm/addrspace.h>
17#include <asm/io.h>
18
19#define PHYS_EMI_CBLOCK P4SEGADDR(0x1ec00000)
20#define PHYS_EMI_DBLOCK P4SEGADDR(0x08000000)
21#define PHYS_FEMI_CBLOCK P4SEGADDR(0x1f800000)
22#define PHYS_FEMI_DBLOCK P4SEGADDR(0x00000000)
23
24#define PHYS_EPBR_BLOCK P4SEGADDR(0x1de00000)
25#define PHYS_DMAC_BLOCK P4SEGADDR(0x1fa00000)
26#define PHYS_PBR_BLOCK P4SEGADDR(0x1fc00000)
27
28static struct resource emi_resources[] = {
29 [0] = {
30 .start = PHYS_EMI_CBLOCK,
31 .end = PHYS_EMI_CBLOCK + 0x00300000 - 1,
32 .flags = IORESOURCE_MEM,
33 },
34 [1] = {
35 .start = PHYS_EMI_DBLOCK,
36 .end = PHYS_EMI_DBLOCK + 0x08000000 - 1,
37 .flags = IORESOURCE_MEM,
38 },
39};
40
41static struct superhyway_device emi_device = {
42 .name = "emi",
43 .num_resources = ARRAY_SIZE(emi_resources),
44 .resource = emi_resources,
45};
46
47static struct resource femi_resources[] = {
48 [0] = {
49 .start = PHYS_FEMI_CBLOCK,
50 .end = PHYS_FEMI_CBLOCK + 0x00100000 - 1,
51 .flags = IORESOURCE_MEM,
52 },
53 [1] = {
54 .start = PHYS_FEMI_DBLOCK,
55 .end = PHYS_FEMI_DBLOCK + 0x08000000 - 1,
56 .flags = IORESOURCE_MEM,
57 },
58};
59
60static struct superhyway_device femi_device = {
61 .name = "femi",
62 .num_resources = ARRAY_SIZE(femi_resources),
63 .resource = femi_resources,
64};
65
66static struct resource epbr_resources[] = {
67 [0] = {
68 .start = P4SEGADDR(0x1e7ffff8),
69 .end = P4SEGADDR(0x1e7ffff8 + (sizeof(u32) * 2) - 1),
70 .flags = IORESOURCE_MEM,
71 },
72 [1] = {
73 .start = PHYS_EPBR_BLOCK,
74 .end = PHYS_EPBR_BLOCK + 0x00a00000 - 1,
75 .flags = IORESOURCE_MEM,
76 },
77};
78
79static struct superhyway_device epbr_device = {
80 .name = "epbr",
81 .num_resources = ARRAY_SIZE(epbr_resources),
82 .resource = epbr_resources,
83};
84
85static struct resource dmac_resource = {
86 .start = PHYS_DMAC_BLOCK,
87 .end = PHYS_DMAC_BLOCK + 0x00100000 - 1,
88 .flags = IORESOURCE_MEM,
89};
90
91static struct superhyway_device dmac_device = {
92 .name = "dmac",
93 .num_resources = 1,
94 .resource = &dmac_resource,
95};
96
97static struct resource pbr_resources[] = {
98 [0] = {
99 .start = P4SEGADDR(0x1ffffff8),
100 .end = P4SEGADDR(0x1ffffff8 + (sizeof(u32) * 2) - 1),
101 .flags = IORESOURCE_MEM,
102 },
103 [1] = {
104 .start = PHYS_PBR_BLOCK,
105 .end = PHYS_PBR_BLOCK + 0x00400000 - (sizeof(u32) * 2) - 1,
106 .flags = IORESOURCE_MEM,
107 },
108};
109
110static struct superhyway_device pbr_device = {
111 .name = "pbr",
112 .num_resources = ARRAY_SIZE(pbr_resources),
113 .resource = pbr_resources,
114};
115
116static struct superhyway_device *sh4202_devices[] __initdata = {
117 &emi_device, &femi_device, &epbr_device, &dmac_device, &pbr_device,
118};
119
120static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
121{
122 u32 vcrh, vcrl;
123 u64 tmp;
124
125 /*
126 * XXX: Even though the SH4-202 Evaluation Device documentation
127 * indicates that VCRL is mapped first with VCRH at a + 0x04
128 * offset, the opposite seems to be true.
129 *
130 * Some modules (PBR and ePBR for instance) also appear to have
131 * VCRL/VCRH flipped in the documentation, but on the SH4-202
132 * itself it appears that these are all consistently mapped with
133 * VCRH preceeding VCRL.
134 *
135 * Do not trust the documentation, for it is evil.
136 */
137 vcrh = ctrl_inl(base);
138 vcrl = ctrl_inl(base + sizeof(u32));
139
140 tmp = ((u64)vcrh << 32) | vcrl;
141 memcpy(vcr, &tmp, sizeof(u64));
142
143 return 0;
144}
145
146static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
147{
148 u64 tmp = *(u64 *)&vcr;
149
150 ctrl_outl((tmp >> 32) & 0xffffffff, base);
151 ctrl_outl(tmp & 0xffffffff, base + sizeof(u32));
152
153 return 0;
154}
155
156static struct superhyway_ops sh4202_superhyway_ops = {
157 .read_vcr = sh4202_read_vcr,
158 .write_vcr = sh4202_write_vcr,
159};
160
161struct superhyway_bus superhyway_channels[] = {
162 { &sh4202_superhyway_ops, },
163 { 0, },
164};
165
166int __init superhyway_scan_bus(struct superhyway_bus *bus)
167{
168 return superhyway_add_devices(bus, sh4202_devices,
169 ARRAY_SIZE(sh4202_devices));
170}
171
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 1fbe5a428e31..1a8be06519ec 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -80,48 +80,11 @@ void ptrace_disable(struct task_struct *child)
80 /* nothing to do.. */ 80 /* nothing to do.. */
81} 81}
82 82
83asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 83long arch_ptrace(struct task_struct *child, long request, long addr, long data)
84{ 84{
85 struct task_struct *child;
86 struct user * dummy = NULL; 85 struct user * dummy = NULL;
87 int ret; 86 int ret;
88 87
89 lock_kernel();
90 ret = -EPERM;
91 if (request == PTRACE_TRACEME) {
92 /* are we already being traced? */
93 if (current->ptrace & PT_PTRACED)
94 goto out;
95 ret = security_ptrace(current->parent, current);
96 if (ret)
97 goto out;
98 /* set the ptrace bit in the process flags. */
99 current->ptrace |= PT_PTRACED;
100 ret = 0;
101 goto out;
102 }
103 ret = -ESRCH;
104 read_lock(&tasklist_lock);
105 child = find_task_by_pid(pid);
106 if (child)
107 get_task_struct(child);
108 read_unlock(&tasklist_lock);
109 if (!child)
110 goto out;
111
112 ret = -EPERM;
113 if (pid == 1) /* you may not mess with init */
114 goto out_tsk;
115
116 if (request == PTRACE_ATTACH) {
117 ret = ptrace_attach(child);
118 goto out_tsk;
119 }
120
121 ret = ptrace_check_attach(child, request == PTRACE_KILL);
122 if (ret < 0)
123 goto out_tsk;
124
125 switch (request) { 88 switch (request) {
126 /* when I and D space are separate, these will need to be fixed. */ 89 /* when I and D space are separate, these will need to be fixed. */
127 case PTRACE_PEEKTEXT: /* read word at location addr. */ 90 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -289,10 +252,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
289 ret = ptrace_request(child, request, addr, data); 252 ret = ptrace_request(child, request, addr, data);
290 break; 253 break;
291 } 254 }
292out_tsk: 255
293 put_task_struct(child);
294out:
295 unlock_kernel();
296 return ret; 256 return ret;
297} 257}
298 258
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 25b9d9ebe858..036050b377cd 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -83,9 +83,9 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name);
83/* ... */ 83/* ... */
84#define COMMAND_LINE ((char *) (PARAM+0x100)) 84#define COMMAND_LINE ((char *) (PARAM+0x100))
85 85
86#define RAMDISK_IMAGE_START_MASK 0x07FF 86#define RAMDISK_IMAGE_START_MASK 0x07FF
87#define RAMDISK_PROMPT_FLAG 0x8000 87#define RAMDISK_PROMPT_FLAG 0x8000
88#define RAMDISK_LOAD_FLAG 0x4000 88#define RAMDISK_LOAD_FLAG 0x4000
89 89
90static char command_line[COMMAND_LINE_SIZE] = { 0, }; 90static char command_line[COMMAND_LINE_SIZE] = { 0, };
91 91
@@ -284,18 +284,6 @@ void __init setup_arch(char **cmdline_p)
284#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) 284#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
285#define PFN_PHYS(x) ((x) << PAGE_SHIFT) 285#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
286 286
287#ifdef CONFIG_DISCONTIGMEM
288 NODE_DATA(0)->bdata = &discontig_node_bdata[0];
289 NODE_DATA(1)->bdata = &discontig_node_bdata[1];
290
291 bootmap_size = init_bootmem_node(NODE_DATA(1),
292 PFN_UP(__MEMORY_START_2ND),
293 PFN_UP(__MEMORY_START_2ND),
294 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
295 free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
296 reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
297#endif
298
299 /* 287 /*
300 * Find the highest page frame number we have available 288 * Find the highest page frame number we have available
301 */ 289 */
@@ -306,10 +294,10 @@ void __init setup_arch(char **cmdline_p)
306 */ 294 */
307 max_low_pfn = max_pfn; 295 max_low_pfn = max_pfn;
308 296
309 /* 297 /*
310 * Partially used pages are not usable - thus 298 * Partially used pages are not usable - thus
311 * we are rounding upwards: 299 * we are rounding upwards:
312 */ 300 */
313 start_pfn = PFN_UP(__pa(_end)); 301 start_pfn = PFN_UP(__pa(_end));
314 302
315 /* 303 /*
@@ -360,12 +348,12 @@ void __init setup_arch(char **cmdline_p)
360 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); 348 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
361 349
362#ifdef CONFIG_BLK_DEV_INITRD 350#ifdef CONFIG_BLK_DEV_INITRD
363 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); 351 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
364 if (&__rd_start != &__rd_end) { 352 if (&__rd_start != &__rd_end) {
365 LOADER_TYPE = 1; 353 LOADER_TYPE = 1;
366 INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START; 354 INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
367 INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start; 355 INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
368 } 356 }
369 357
370 if (LOADER_TYPE && INITRD_START) { 358 if (LOADER_TYPE && INITRD_START) {
371 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { 359 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 4e9c854845a4..e342565f75fb 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -51,11 +51,6 @@ unsigned long mmu_context_cache = NO_CONTEXT;
51#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) 51#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
52#endif 52#endif
53 53
54#ifdef CONFIG_DISCONTIGMEM
55pg_data_t discontig_page_data[MAX_NUMNODES];
56bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
57#endif
58
59void (*copy_page)(void *from, void *to); 54void (*copy_page)(void *from, void *to);
60void (*clear_page)(void *to); 55void (*clear_page)(void *to);
61 56
@@ -216,15 +211,6 @@ void __init paging_init(void)
216#endif 211#endif
217 NODE_DATA(0)->node_mem_map = NULL; 212 NODE_DATA(0)->node_mem_map = NULL;
218 free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); 213 free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
219
220#ifdef CONFIG_DISCONTIGMEM
221 /*
222 * And for discontig, do some more fixups on the zone sizes..
223 */
224 zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
225 zones_size[ZONE_NORMAL] = 0;
226 free_area_init_node(1, NODE_DATA(1), zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0);
227#endif
228} 214}
229 215
230void __init mem_init(void) 216void __init mem_init(void)
@@ -248,7 +234,7 @@ void __init mem_init(void)
248 memset(empty_zero_page, 0, PAGE_SIZE); 234 memset(empty_zero_page, 0, PAGE_SIZE);
249 __flush_wback_region(empty_zero_page, PAGE_SIZE); 235 __flush_wback_region(empty_zero_page, PAGE_SIZE);
250 236
251 /* 237 /*
252 * Setup wrappers for copy/clear_page(), these will get overridden 238 * Setup wrappers for copy/clear_page(), these will get overridden
253 * later in the boot process if a better method is available. 239 * later in the boot process if a better method is available.
254 */ 240 */
@@ -257,9 +243,6 @@ void __init mem_init(void)
257 243
258 /* this will put all low memory onto the freelists */ 244 /* this will put all low memory onto the freelists */
259 totalram_pages += free_all_bootmem_node(NODE_DATA(0)); 245 totalram_pages += free_all_bootmem_node(NODE_DATA(0));
260#ifdef CONFIG_DISCONTIGMEM
261 totalram_pages += free_all_bootmem_node(NODE_DATA(1));
262#endif
263 reservedpages = 0; 246 reservedpages = 0;
264 for (tmp = 0; tmp < num_physpages; tmp++) 247 for (tmp = 0; tmp < num_physpages; tmp++)
265 /* 248 /*
@@ -286,7 +269,7 @@ void __init mem_init(void)
286void free_initmem(void) 269void free_initmem(void)
287{ 270{
288 unsigned long addr; 271 unsigned long addr;
289 272
290 addr = (unsigned long)(&__init_begin); 273 addr = (unsigned long)(&__init_begin);
291 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { 274 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
292 ClearPageReserved(virt_to_page(addr)); 275 ClearPageReserved(virt_to_page(addr));
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index 7a0d5c10bf20..46b09e26e082 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -40,12 +40,17 @@ void update_mmu_cache(struct vm_area_struct * vma,
40 return; 40 return;
41 41
42#if defined(CONFIG_SH7705_CACHE_32KB) 42#if defined(CONFIG_SH7705_CACHE_32KB)
43 struct page *page; 43 {
44 page = pte_page(pte); 44 struct page *page = pte_page(pte);
45 if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) { 45 unsigned long pfn = pte_pfn(pte);
46 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK; 46
47 __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE); 47 if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
48 __set_bit(PG_mapped, &page->flags); 48 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
49
50 __flush_wback_region((void *)P1SEGADDR(phys),
51 PAGE_SIZE);
52 __set_bit(PG_mapped, &page->flags);
53 }
49 } 54 }
50#endif 55#endif
51 56
@@ -80,7 +85,7 @@ void __flush_tlb_page(unsigned long asid, unsigned long page)
80 */ 85 */
81 addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000); 86 addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000);
82 data = (page & 0xfffe0000) | asid; /* VALID bit is off */ 87 data = (page & 0xfffe0000) | asid; /* VALID bit is off */
83 88
84 if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) { 89 if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) {
85 addr |= MMU_PAGE_ASSOC_BIT; 90 addr |= MMU_PAGE_ASSOC_BIT;
86 ways = 1; /* we already know the way .. */ 91 ways = 1; /* we already know the way .. */
diff --git a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile
deleted file mode 100644
index 99e1c68673cf..000000000000
--- a/arch/sh/ramdisk/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
1#
2# Makefile for a ramdisk image
3#
4
5obj-y += ramdisk.o
6
7
8O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32)
9img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
10# add $(src) when $(img) is relative
11img := $(subst $(src)//,/,$(src)/$(img))
12
13quiet_cmd_ramdisk = LD $@
14define cmd_ramdisk
15 $(LD) -T $(srctree)/$(src)/ld.script -b binary --oformat $(O_FORMAT) \
16 -o $@ $(img)
17endef
18
19$(obj)/ramdisk.o: $(img) $(srctree)/$(src)/ld.script
20 $(call cmd,ramdisk)
diff --git a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script
deleted file mode 100644
index 94beee248c04..000000000000
--- a/arch/sh/ramdisk/ld.script
+++ /dev/null
@@ -1,9 +0,0 @@
1OUTPUT_ARCH(sh)
2SECTIONS
3{
4 .initrd :
5 {
6 *(.data)
7 }
8}
9
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 71f2eec00b99..cd22e9471316 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -28,6 +28,7 @@
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/user.h> 29#include <linux/user.h>
30#include <linux/signal.h> 30#include <linux/signal.h>
31#include <linux/syscalls.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
@@ -121,61 +122,11 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
121 return 0; 122 return 0;
122} 123}
123 124
124asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 125
126long arch_ptrace(struct task_struct *child, long request, long addr, long data)
125{ 127{
126 struct task_struct *child;
127 extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
128#define WPC_DBRMODE 0x0d104008
129 static int first_call = 1;
130 int ret; 128 int ret;
131 129
132 lock_kernel();
133
134 if (first_call) {
135 /* Set WPC.DBRMODE to 0. This makes all debug events get
136 * delivered through RESVEC, i.e. into the handlers in entry.S.
137 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
138 * would normally be left set to 1, which makes debug events get
139 * delivered through DBRVEC, i.e. into the remote gdb's
140 * handlers. This prevents ptrace getting them, and confuses
141 * the remote gdb.) */
142 printk("DBRMODE set to 0 to permit native debugging\n");
143 poke_real_address_q(WPC_DBRMODE, 0);
144 first_call = 0;
145 }
146
147 ret = -EPERM;
148 if (request == PTRACE_TRACEME) {
149 /* are we already being traced? */
150 if (current->ptrace & PT_PTRACED)
151 goto out;
152 /* set the ptrace bit in the process flags. */
153 current->ptrace |= PT_PTRACED;
154 ret = 0;
155 goto out;
156 }
157 ret = -ESRCH;
158 read_lock(&tasklist_lock);
159 child = find_task_by_pid(pid);
160 if (child)
161 get_task_struct(child);
162 read_unlock(&tasklist_lock);
163 if (!child)
164 goto out;
165
166 ret = -EPERM;
167 if (pid == 1) /* you may not mess with init */
168 goto out_tsk;
169
170 if (request == PTRACE_ATTACH) {
171 ret = ptrace_attach(child);
172 goto out_tsk;
173 }
174
175 ret = ptrace_check_attach(child, request == PTRACE_KILL);
176 if (ret < 0)
177 goto out_tsk;
178
179 switch (request) { 130 switch (request) {
180 /* when I and D space are separate, these will need to be fixed. */ 131 /* when I and D space are separate, these will need to be fixed. */
181 case PTRACE_PEEKTEXT: /* read word at location addr. */ 132 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
313 ret = ptrace_request(child, request, addr, data); 264 ret = ptrace_request(child, request, addr, data);
314 break; 265 break;
315 } 266 }
316out_tsk:
317 put_task_struct(child);
318out:
319 unlock_kernel();
320 return ret; 267 return ret;
321} 268}
322 269
270asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
271{
272 extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
273#define WPC_DBRMODE 0x0d104008
274 static int first_call = 1;
275
276 lock_kernel();
277 if (first_call) {
278 /* Set WPC.DBRMODE to 0. This makes all debug events get
279 * delivered through RESVEC, i.e. into the handlers in entry.S.
280 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
281 * would normally be left set to 1, which makes debug events get
282 * delivered through DBRVEC, i.e. into the remote gdb's
283 * handlers. This prevents ptrace getting them, and confuses
284 * the remote gdb.) */
285 printk("DBRMODE set to 0 to permit native debugging\n");
286 poke_real_address_q(WPC_DBRMODE, 0);
287 first_call = 0;
288 }
289 unlock_kernel();
290
291 return sys_ptrace(request, pid, addr, data);
292}
293
323asmlinkage void syscall_trace(void) 294asmlinkage void syscall_trace(void)
324{ 295{
325 struct task_struct *tsk = current; 296 struct task_struct *tsk = current;
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S
index a3d037805f1c..c0079d54c850 100644
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh64/kernel/syscalls.S
@@ -46,7 +46,7 @@ sys_call_table:
46 .long sys_setuid16 46 .long sys_setuid16
47 .long sys_getuid16 47 .long sys_getuid16
48 .long sys_stime /* 25 */ 48 .long sys_stime /* 25 */
49 .long sys_ptrace 49 .long sh64_ptrace
50 .long sys_alarm 50 .long sys_alarm
51 .long sys_fstat 51 .long sys_fstat
52 .long sys_pause 52 .long sys_pause
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 1e9d8638a28a..3fded69b1922 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -377,8 +377,21 @@ source "drivers/fc4/Kconfig"
377 377
378source "fs/Kconfig" 378source "fs/Kconfig"
379 379
380menu "Instrumentation Support"
381 depends on EXPERIMENTAL
382
380source "arch/sparc64/oprofile/Kconfig" 383source "arch/sparc64/oprofile/Kconfig"
381 384
385config KPROBES
386 bool "Kprobes (EXPERIMENTAL)"
387 help
388 Kprobes allows you to trap at almost any kernel address and
389 execute a callback function. register_kprobe() establishes
390 a probepoint and specifies the callback. Kprobes is useful
391 for kernel debugging, non-intrusive instrumentation and testing.
392 If in doubt, say "N".
393endmenu
394
382source "arch/sparc64/Kconfig.debug" 395source "arch/sparc64/Kconfig.debug"
383 396
384source "security/Kconfig" 397source "security/Kconfig"
diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug
index fa06ea04837b..3e31be494e54 100644
--- a/arch/sparc64/Kconfig.debug
+++ b/arch/sparc64/Kconfig.debug
@@ -11,16 +11,6 @@ config DEBUG_STACK_USAGE
11 11
12 This option will slow down process creation somewhat. 12 This option will slow down process creation somewhat.
13 13
14config KPROBES
15 bool "Kprobes"
16 depends on DEBUG_KERNEL
17 help
18 Kprobes allows you to trap at almost any kernel address and
19 execute a callback function. register_kprobe() establishes
20 a probepoint and specifies the callback. Kprobes is useful
21 for kernel debugging, non-intrusive instrumentation and testing.
22 If in doubt, say "N".
23
24config DEBUG_DCFLUSH 14config DEBUG_DCFLUSH
25 bool "D-cache flush debugging" 15 bool "D-cache flush debugging"
26 depends on DEBUG_KERNEL 16 depends on DEBUG_KERNEL
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 0d66d07c8c6e..96bd09b098f4 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -38,6 +38,9 @@
38 * - Mark that we are no longer actively in a kprobe. 38 * - Mark that we are no longer actively in a kprobe.
39 */ 39 */
40 40
41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43
41int __kprobes arch_prepare_kprobe(struct kprobe *p) 44int __kprobes arch_prepare_kprobe(struct kprobe *p)
42{ 45{
43 return 0; 46 return 0;
@@ -66,46 +69,39 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
66{ 69{
67} 70}
68 71
69static struct kprobe *current_kprobe; 72static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
70static unsigned long current_kprobe_orig_tnpc;
71static unsigned long current_kprobe_orig_tstate_pil;
72static unsigned int kprobe_status;
73static struct kprobe *kprobe_prev;
74static unsigned long kprobe_orig_tnpc_prev;
75static unsigned long kprobe_orig_tstate_pil_prev;
76static unsigned int kprobe_status_prev;
77
78static inline void save_previous_kprobe(void)
79{ 73{
80 kprobe_status_prev = kprobe_status; 74 kcb->prev_kprobe.kp = kprobe_running();
81 kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc; 75 kcb->prev_kprobe.status = kcb->kprobe_status;
82 kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil; 76 kcb->prev_kprobe.orig_tnpc = kcb->kprobe_orig_tnpc;
83 kprobe_prev = current_kprobe; 77 kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
84} 78}
85 79
86static inline void restore_previous_kprobe(void) 80static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
87{ 81{
88 kprobe_status = kprobe_status_prev; 82 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
89 current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev; 83 kcb->kprobe_status = kcb->prev_kprobe.status;
90 current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev; 84 kcb->kprobe_orig_tnpc = kcb->prev_kprobe.orig_tnpc;
91 current_kprobe = kprobe_prev; 85 kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
92} 86}
93 87
94static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs) 88static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
89 struct kprobe_ctlblk *kcb)
95{ 90{
96 current_kprobe_orig_tnpc = regs->tnpc; 91 __get_cpu_var(current_kprobe) = p;
97 current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); 92 kcb->kprobe_orig_tnpc = regs->tnpc;
98 current_kprobe = p; 93 kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
99} 94}
100 95
101static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 96static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
97 struct kprobe_ctlblk *kcb)
102{ 98{
103 regs->tstate |= TSTATE_PIL; 99 regs->tstate |= TSTATE_PIL;
104 100
105 /*single step inline, if it a breakpoint instruction*/ 101 /*single step inline, if it a breakpoint instruction*/
106 if (p->opcode == BREAKPOINT_INSTRUCTION) { 102 if (p->opcode == BREAKPOINT_INSTRUCTION) {
107 regs->tpc = (unsigned long) p->addr; 103 regs->tpc = (unsigned long) p->addr;
108 regs->tnpc = current_kprobe_orig_tnpc; 104 regs->tnpc = kcb->kprobe_orig_tnpc;
109 } else { 105 } else {
110 regs->tpc = (unsigned long) &p->ainsn.insn[0]; 106 regs->tpc = (unsigned long) &p->ainsn.insn[0];
111 regs->tnpc = (unsigned long) &p->ainsn.insn[1]; 107 regs->tnpc = (unsigned long) &p->ainsn.insn[1];
@@ -117,19 +113,21 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
117 struct kprobe *p; 113 struct kprobe *p;
118 void *addr = (void *) regs->tpc; 114 void *addr = (void *) regs->tpc;
119 int ret = 0; 115 int ret = 0;
116 struct kprobe_ctlblk *kcb;
120 117
118 /*
119 * We don't want to be preempted for the entire
120 * duration of kprobe processing
121 */
121 preempt_disable(); 122 preempt_disable();
123 kcb = get_kprobe_ctlblk();
122 124
123 if (kprobe_running()) { 125 if (kprobe_running()) {
124 /* We *are* holding lock here, so this is safe.
125 * Disarm the probe we just hit, and ignore it.
126 */
127 p = get_kprobe(addr); 126 p = get_kprobe(addr);
128 if (p) { 127 if (p) {
129 if (kprobe_status == KPROBE_HIT_SS) { 128 if (kcb->kprobe_status == KPROBE_HIT_SS) {
130 regs->tstate = ((regs->tstate & ~TSTATE_PIL) | 129 regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
131 current_kprobe_orig_tstate_pil); 130 kcb->kprobe_orig_tstate_pil);
132 unlock_kprobes();
133 goto no_kprobe; 131 goto no_kprobe;
134 } 132 }
135 /* We have reentered the kprobe_handler(), since 133 /* We have reentered the kprobe_handler(), since
@@ -138,25 +136,22 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
138 * just single step on the instruction of the new probe 136 * just single step on the instruction of the new probe
139 * without calling any user handlers. 137 * without calling any user handlers.
140 */ 138 */
141 save_previous_kprobe(); 139 save_previous_kprobe(kcb);
142 set_current_kprobe(p, regs); 140 set_current_kprobe(p, regs, kcb);
143 p->nmissed++; 141 p->nmissed++;
144 kprobe_status = KPROBE_REENTER; 142 kcb->kprobe_status = KPROBE_REENTER;
145 prepare_singlestep(p, regs); 143 prepare_singlestep(p, regs, kcb);
146 return 1; 144 return 1;
147 } else { 145 } else {
148 p = current_kprobe; 146 p = __get_cpu_var(current_kprobe);
149 if (p->break_handler && p->break_handler(p, regs)) 147 if (p->break_handler && p->break_handler(p, regs))
150 goto ss_probe; 148 goto ss_probe;
151 } 149 }
152 /* If it's not ours, can't be delete race, (we hold lock). */
153 goto no_kprobe; 150 goto no_kprobe;
154 } 151 }
155 152
156 lock_kprobes();
157 p = get_kprobe(addr); 153 p = get_kprobe(addr);
158 if (!p) { 154 if (!p) {
159 unlock_kprobes();
160 if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) { 155 if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
161 /* 156 /*
162 * The breakpoint instruction was removed right 157 * The breakpoint instruction was removed right
@@ -171,14 +166,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
171 goto no_kprobe; 166 goto no_kprobe;
172 } 167 }
173 168
174 set_current_kprobe(p, regs); 169 set_current_kprobe(p, regs, kcb);
175 kprobe_status = KPROBE_HIT_ACTIVE; 170 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
176 if (p->pre_handler && p->pre_handler(p, regs)) 171 if (p->pre_handler && p->pre_handler(p, regs))
177 return 1; 172 return 1;
178 173
179ss_probe: 174ss_probe:
180 prepare_singlestep(p, regs); 175 prepare_singlestep(p, regs, kcb);
181 kprobe_status = KPROBE_HIT_SS; 176 kcb->kprobe_status = KPROBE_HIT_SS;
182 return 1; 177 return 1;
183 178
184no_kprobe: 179no_kprobe:
@@ -260,11 +255,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
260 * This function prepares to return from the post-single-step 255 * This function prepares to return from the post-single-step
261 * breakpoint trap. 256 * breakpoint trap.
262 */ 257 */
263static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) 258static void __kprobes resume_execution(struct kprobe *p,
259 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
264{ 260{
265 u32 insn = p->ainsn.insn[0]; 261 u32 insn = p->ainsn.insn[0];
266 262
267 regs->tpc = current_kprobe_orig_tnpc; 263 regs->tpc = kcb->kprobe_orig_tnpc;
268 regs->tnpc = relbranch_fixup(insn, 264 regs->tnpc = relbranch_fixup(insn,
269 (unsigned long) p->addr, 265 (unsigned long) p->addr,
270 (unsigned long) &p->ainsn.insn[0], 266 (unsigned long) &p->ainsn.insn[0],
@@ -272,44 +268,48 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
272 retpc_fixup(regs, insn, (unsigned long) p->addr); 268 retpc_fixup(regs, insn, (unsigned long) p->addr);
273 269
274 regs->tstate = ((regs->tstate & ~TSTATE_PIL) | 270 regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
275 current_kprobe_orig_tstate_pil); 271 kcb->kprobe_orig_tstate_pil);
276} 272}
277 273
278static inline int post_kprobe_handler(struct pt_regs *regs) 274static inline int post_kprobe_handler(struct pt_regs *regs)
279{ 275{
280 if (!kprobe_running()) 276 struct kprobe *cur = kprobe_running();
277 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
278
279 if (!cur)
281 return 0; 280 return 0;
282 281
283 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { 282 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
284 kprobe_status = KPROBE_HIT_SSDONE; 283 kcb->kprobe_status = KPROBE_HIT_SSDONE;
285 current_kprobe->post_handler(current_kprobe, regs, 0); 284 cur->post_handler(cur, regs, 0);
286 } 285 }
287 286
288 resume_execution(current_kprobe, regs); 287 resume_execution(cur, regs, kcb);
289 288
290 /*Restore back the original saved kprobes variables and continue. */ 289 /*Restore back the original saved kprobes variables and continue. */
291 if (kprobe_status == KPROBE_REENTER) { 290 if (kcb->kprobe_status == KPROBE_REENTER) {
292 restore_previous_kprobe(); 291 restore_previous_kprobe(kcb);
293 goto out; 292 goto out;
294 } 293 }
295 unlock_kprobes(); 294 reset_current_kprobe();
296out: 295out:
297 preempt_enable_no_resched(); 296 preempt_enable_no_resched();
298 297
299 return 1; 298 return 1;
300} 299}
301 300
302/* Interrupts disabled, kprobe_lock held. */
303static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 301static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
304{ 302{
305 if (current_kprobe->fault_handler 303 struct kprobe *cur = kprobe_running();
306 && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) 304 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
305
306 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
307 return 1; 307 return 1;
308 308
309 if (kprobe_status & KPROBE_HIT_SS) { 309 if (kcb->kprobe_status & KPROBE_HIT_SS) {
310 resume_execution(current_kprobe, regs); 310 resume_execution(cur, regs, kcb);
311 311
312 unlock_kprobes(); 312 reset_current_kprobe();
313 preempt_enable_no_resched(); 313 preempt_enable_no_resched();
314 } 314 }
315 return 0; 315 return 0;
@@ -322,29 +322,30 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
322 unsigned long val, void *data) 322 unsigned long val, void *data)
323{ 323{
324 struct die_args *args = (struct die_args *)data; 324 struct die_args *args = (struct die_args *)data;
325 int ret = NOTIFY_DONE;
326
325 switch (val) { 327 switch (val) {
326 case DIE_DEBUG: 328 case DIE_DEBUG:
327 if (kprobe_handler(args->regs)) 329 if (kprobe_handler(args->regs))
328 return NOTIFY_STOP; 330 ret = NOTIFY_STOP;
329 break; 331 break;
330 case DIE_DEBUG_2: 332 case DIE_DEBUG_2:
331 if (post_kprobe_handler(args->regs)) 333 if (post_kprobe_handler(args->regs))
332 return NOTIFY_STOP; 334 ret = NOTIFY_STOP;
333 break; 335 break;
334 case DIE_GPF: 336 case DIE_GPF:
335 if (kprobe_running() &&
336 kprobe_fault_handler(args->regs, args->trapnr))
337 return NOTIFY_STOP;
338 break;
339 case DIE_PAGE_FAULT: 337 case DIE_PAGE_FAULT:
338 /* kprobe_running() needs smp_processor_id() */
339 preempt_disable();
340 if (kprobe_running() && 340 if (kprobe_running() &&
341 kprobe_fault_handler(args->regs, args->trapnr)) 341 kprobe_fault_handler(args->regs, args->trapnr))
342 return NOTIFY_STOP; 342 ret = NOTIFY_STOP;
343 preempt_enable();
343 break; 344 break;
344 default: 345 default:
345 break; 346 break;
346 } 347 }
347 return NOTIFY_DONE; 348 return ret;
348} 349}
349 350
350asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, 351asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
@@ -368,24 +369,21 @@ asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
368} 369}
369 370
370/* Jprobes support. */ 371/* Jprobes support. */
371static struct pt_regs jprobe_saved_regs;
372static struct pt_regs *jprobe_saved_regs_location;
373static struct sparc_stackf jprobe_saved_stack;
374
375int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 372int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
376{ 373{
377 struct jprobe *jp = container_of(p, struct jprobe, kp); 374 struct jprobe *jp = container_of(p, struct jprobe, kp);
375 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
378 376
379 jprobe_saved_regs_location = regs; 377 kcb->jprobe_saved_regs_location = regs;
380 memcpy(&jprobe_saved_regs, regs, sizeof(*regs)); 378 memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
381 379
382 /* Save a whole stack frame, this gets arguments 380 /* Save a whole stack frame, this gets arguments
383 * pushed onto the stack after using up all the 381 * pushed onto the stack after using up all the
384 * arg registers. 382 * arg registers.
385 */ 383 */
386 memcpy(&jprobe_saved_stack, 384 memcpy(&(kcb->jprobe_saved_stack),
387 (char *) (regs->u_regs[UREG_FP] + STACK_BIAS), 385 (char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
388 sizeof(jprobe_saved_stack)); 386 sizeof(kcb->jprobe_saved_stack));
389 387
390 regs->tpc = (unsigned long) jp->entry; 388 regs->tpc = (unsigned long) jp->entry;
391 regs->tnpc = ((unsigned long) jp->entry) + 0x4UL; 389 regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
@@ -396,7 +394,6 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
396 394
397void __kprobes jprobe_return(void) 395void __kprobes jprobe_return(void)
398{ 396{
399 preempt_enable_no_resched();
400 __asm__ __volatile__( 397 __asm__ __volatile__(
401 ".globl jprobe_return_trap_instruction\n" 398 ".globl jprobe_return_trap_instruction\n"
402"jprobe_return_trap_instruction:\n\t" 399"jprobe_return_trap_instruction:\n\t"
@@ -410,14 +407,15 @@ extern void __show_regs(struct pt_regs * regs);
410int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 407int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
411{ 408{
412 u32 *addr = (u32 *) regs->tpc; 409 u32 *addr = (u32 *) regs->tpc;
410 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
413 411
414 if (addr == (u32 *) jprobe_return_trap_instruction) { 412 if (addr == (u32 *) jprobe_return_trap_instruction) {
415 if (jprobe_saved_regs_location != regs) { 413 if (kcb->jprobe_saved_regs_location != regs) {
416 printk("JPROBE: Current regs (%p) does not match " 414 printk("JPROBE: Current regs (%p) does not match "
417 "saved regs (%p).\n", 415 "saved regs (%p).\n",
418 regs, jprobe_saved_regs_location); 416 regs, kcb->jprobe_saved_regs_location);
419 printk("JPROBE: Saved registers\n"); 417 printk("JPROBE: Saved registers\n");
420 __show_regs(jprobe_saved_regs_location); 418 __show_regs(kcb->jprobe_saved_regs_location);
421 printk("JPROBE: Current registers\n"); 419 printk("JPROBE: Current registers\n");
422 __show_regs(regs); 420 __show_regs(regs);
423 BUG(); 421 BUG();
@@ -426,12 +424,13 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
426 * first so that UREG_FP is the original one for 424 * first so that UREG_FP is the original one for
427 * the stack frame restore. 425 * the stack frame restore.
428 */ 426 */
429 memcpy(regs, &jprobe_saved_regs, sizeof(*regs)); 427 memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
430 428
431 memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS), 429 memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
432 &jprobe_saved_stack, 430 &(kcb->jprobe_saved_stack),
433 sizeof(jprobe_saved_stack)); 431 sizeof(kcb->jprobe_saved_stack));
434 432
433 preempt_enable_no_resched();
435 return 1; 434 return 1;
436 } 435 }
437 return 0; 436 return 0;
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index 686e526bec04..b35dc8dc995a 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -388,10 +388,8 @@ err_out:
388 kfree(driver); 388 kfree(driver);
389 cpufreq_us2e_driver = NULL; 389 cpufreq_us2e_driver = NULL;
390 } 390 }
391 if (us2e_freq_table) { 391 kfree(us2e_freq_table);
392 kfree(us2e_freq_table); 392 us2e_freq_table = NULL;
393 us2e_freq_table = NULL;
394 }
395 return ret; 393 return ret;
396 } 394 }
397 395
@@ -402,7 +400,6 @@ static void __exit us2e_freq_exit(void)
402{ 400{
403 if (cpufreq_us2e_driver) { 401 if (cpufreq_us2e_driver) {
404 cpufreq_unregister_driver(cpufreq_us2e_driver); 402 cpufreq_unregister_driver(cpufreq_us2e_driver);
405
406 kfree(cpufreq_us2e_driver); 403 kfree(cpufreq_us2e_driver);
407 cpufreq_us2e_driver = NULL; 404 cpufreq_us2e_driver = NULL;
408 kfree(us2e_freq_table); 405 kfree(us2e_freq_table);
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 0340041f6143..6d1f9a3c464f 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -249,10 +249,8 @@ err_out:
249 kfree(driver); 249 kfree(driver);
250 cpufreq_us3_driver = NULL; 250 cpufreq_us3_driver = NULL;
251 } 251 }
252 if (us3_freq_table) { 252 kfree(us3_freq_table);
253 kfree(us3_freq_table); 253 us3_freq_table = NULL;
254 us3_freq_table = NULL;
255 }
256 return ret; 254 return ret;
257 } 255 }
258 256
@@ -263,7 +261,6 @@ static void __exit us3_freq_exit(void)
263{ 261{
264 if (cpufreq_us3_driver) { 262 if (cpufreq_us3_driver) {
265 cpufreq_unregister_driver(cpufreq_us3_driver); 263 cpufreq_unregister_driver(cpufreq_us3_driver);
266
267 kfree(cpufreq_us3_driver); 264 kfree(cpufreq_us3_driver);
268 cpufreq_us3_driver = NULL; 265 cpufreq_us3_driver = NULL;
269 kfree(us3_freq_table); 266 kfree(us3_freq_table);
diff --git a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
index 5ade19801b97..d8a84088471a 100644
--- a/arch/sparc64/oprofile/Kconfig
+++ b/arch/sparc64/oprofile/Kconfig
@@ -1,7 +1,3 @@
1
2menu "Profiling support"
3 depends on EXPERIMENTAL
4
5config PROFILING 1config PROFILING
6 bool "Profiling support (EXPERIMENTAL)" 2 bool "Profiling support (EXPERIMENTAL)"
7 help 3 help
@@ -19,5 +15,3 @@ config OPROFILE
19 15
20 If unsure, say N. 16 If unsure, say N.
21 17
22endmenu
23
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index cd06ed7d842d..3b5f47c46907 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -65,6 +65,30 @@ config STATIC_LINK
65 chroot, and you disable CONFIG_MODE_TT, you probably want to say Y 65 chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
66 here. 66 here.
67 67
68config HOST_2G_2G
69 bool "2G/2G host address space split"
70 default n
71 depends on MODE_TT
72 help
73 This is needed when the host on which you run has a 2G/2G memory
74 split, instead of the customary 3G/1G.
75
76 Note that to enable such a host
77 configuration, which makes sense only in some cases, you need special
78 host patches.
79
80 So, if you do not know what to do here, say 'N'.
81
82config KERNEL_HALF_GIGS
83 int "Kernel address space size (in .5G units)"
84 default "1"
85 depends on MODE_TT
86 help
87 This determines the amount of address space that UML will allocate for
88 its own, measured in half Gigabyte units. The default is 1.
89 Change this only if you need to boot UML with an unusually large amount
90 of physical memory.
91
68config MODE_SKAS 92config MODE_SKAS
69 bool "Separate Kernel Address Space support" 93 bool "Separate Kernel Address Space support"
70 default y 94 default y
@@ -182,19 +206,6 @@ config MAGIC_SYSRQ
182 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y 206 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
183 unless you really know what this hack does. 207 unless you really know what this hack does.
184 208
185config HOST_2G_2G
186 bool "2G/2G host address space split"
187 default n
188 help
189 This is needed when the host on which you run has a 2G/2G memory
190 split, instead of the customary 3G/1G.
191
192 Note that to enable such a host
193 configuration, which makes sense only in some cases, you need special
194 host patches.
195
196 So, if you do not know what to do here, say 'N'.
197
198config SMP 209config SMP
199 bool "Symmetric multi-processing support (EXPERIMENTAL)" 210 bool "Symmetric multi-processing support (EXPERIMENTAL)"
200 default n 211 default n
@@ -241,15 +252,6 @@ config NEST_LEVEL
241 set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS. 252 set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
242 Only change this if you are running nested UMLs. 253 Only change this if you are running nested UMLs.
243 254
244config KERNEL_HALF_GIGS
245 int "Kernel address space size (in .5G units)"
246 default "1"
247 help
248 This determines the amount of address space that UML will allocate for
249 its own, measured in half Gigabyte units. The default is 1.
250 Change this only if you need to boot UML with an unusually large amount
251 of physical memory.
252
253config HIGHMEM 255config HIGHMEM
254 bool "Highmem support" 256 bool "Highmem support"
255 depends on !64BIT 257 depends on !64BIT
diff --git a/arch/um/Makefile b/arch/um/Makefile
index e1ffad224605..e55d32e903bc 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -60,7 +60,7 @@ AFLAGS += $(ARCH_INCLUDE)
60 60
61USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) 61USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
62USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ 62USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
63 $(MODE_INCLUDE) 63 $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
64 64
65# -Derrno=kernel_errno - This turns all kernel references to errno into 65# -Derrno=kernel_errno - This turns all kernel references to errno into
66# kernel_errno to separate them from the libc errno. This allows -fno-common 66# kernel_errno to separate them from the libc errno. This allows -fno-common
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index aef7c50f8e13..1f7dcb064aee 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -17,8 +17,6 @@ ifeq ("$(origin SUBARCH)", "command line")
17ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") 17ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
18CFLAGS += $(call cc-option,-m32) 18CFLAGS += $(call cc-option,-m32)
19USER_CFLAGS += $(call cc-option,-m32) 19USER_CFLAGS += $(call cc-option,-m32)
20HOSTCFLAGS += $(call cc-option,-m32)
21HOSTLDFLAGS += $(call cc-option,-m32)
22AFLAGS += $(call cc-option,-m32) 20AFLAGS += $(call cc-option,-m32)
23LINK-y += $(call cc-option,-m32) 21LINK-y += $(call cc-option,-m32)
24UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) 22UML_OBJCOPYFLAGS += -F $(ELF_FORMAT)
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index de3bce71aeb3..1c55d5802489 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -16,7 +16,6 @@
16#include "user_util.h" 16#include "user_util.h"
17#include "chan_user.h" 17#include "chan_user.h"
18#include "user.h" 18#include "user.h"
19#include "helper.h"
20#include "os.h" 19#include "os.h"
21#include "choose-mode.h" 20#include "choose-mode.h"
22#include "mode.h" 21#include "mode.h"
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 147ec19f6bb9..49acb2badf32 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -46,7 +46,6 @@
46#include <linux/smp_lock.h> 46#include <linux/smp_lock.h>
47#include <linux/init.h> 47#include <linux/init.h>
48#include <asm/uaccess.h> 48#include <asm/uaccess.h>
49#include "helper.h"
50#include "mconsole.h" 49#include "mconsole.h"
51 50
52MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index d934181b8d4c..def013b5a3c7 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -8,7 +8,6 @@
8#include <errno.h> 8#include <errno.h>
9#include "user_util.h" 9#include "user_util.h"
10#include "user.h" 10#include "user.h"
11#include "helper.h"
12#include "mconsole.h" 11#include "mconsole.h"
13#include "os.h" 12#include "os.h"
14#include "choose-mode.h" 13#include "choose-mode.h"
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 721e2601a75d..fe865d9a3721 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -96,7 +96,6 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
96static int uml_net_open(struct net_device *dev) 96static int uml_net_open(struct net_device *dev)
97{ 97{
98 struct uml_net_private *lp = dev->priv; 98 struct uml_net_private *lp = dev->priv;
99 char addr[sizeof("255.255.255.255\0")];
100 int err; 99 int err;
101 100
102 spin_lock(&lp->lock); 101 spin_lock(&lp->lock);
@@ -107,7 +106,7 @@ static int uml_net_open(struct net_device *dev)
107 } 106 }
108 107
109 if(!lp->have_mac){ 108 if(!lp->have_mac){
110 dev_ip_addr(dev, addr, &lp->mac[2]); 109 dev_ip_addr(dev, &lp->mac[2]);
111 set_ether_mac(dev, lp->mac); 110 set_ether_mac(dev, lp->mac);
112 } 111 }
113 112
@@ -664,8 +663,6 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
664 void *ptr) 663 void *ptr)
665{ 664{
666 struct in_ifaddr *ifa = ptr; 665 struct in_ifaddr *ifa = ptr;
667 u32 addr = ifa->ifa_address;
668 u32 netmask = ifa->ifa_mask;
669 struct net_device *dev = ifa->ifa_dev->dev; 666 struct net_device *dev = ifa->ifa_dev->dev;
670 struct uml_net_private *lp; 667 struct uml_net_private *lp;
671 void (*proc)(unsigned char *, unsigned char *, void *); 668 void (*proc)(unsigned char *, unsigned char *, void *);
@@ -685,14 +682,8 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
685 break; 682 break;
686 } 683 }
687 if(proc != NULL){ 684 if(proc != NULL){
688 addr_buf[0] = addr & 0xff; 685 memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
689 addr_buf[1] = (addr >> 8) & 0xff; 686 memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
690 addr_buf[2] = (addr >> 16) & 0xff;
691 addr_buf[3] = addr >> 24;
692 netmask_buf[0] = netmask & 0xff;
693 netmask_buf[1] = (netmask >> 8) & 0xff;
694 netmask_buf[2] = (netmask >> 16) & 0xff;
695 netmask_buf[3] = netmask >> 24;
696 (*proc)(addr_buf, netmask_buf, &lp->user); 687 (*proc)(addr_buf, netmask_buf, &lp->user);
697 } 688 }
698 return(NOTIFY_DONE); 689 return(NOTIFY_DONE);
@@ -774,27 +765,18 @@ int setup_etheraddr(char *str, unsigned char *addr)
774 return(1); 765 return(1);
775} 766}
776 767
777void dev_ip_addr(void *d, char *buf, char *bin_buf) 768void dev_ip_addr(void *d, unsigned char *bin_buf)
778{ 769{
779 struct net_device *dev = d; 770 struct net_device *dev = d;
780 struct in_device *ip = dev->ip_ptr; 771 struct in_device *ip = dev->ip_ptr;
781 struct in_ifaddr *in; 772 struct in_ifaddr *in;
782 u32 addr;
783 773
784 if((ip == NULL) || ((in = ip->ifa_list) == NULL)){ 774 if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
785 printk(KERN_WARNING "dev_ip_addr - device not assigned an " 775 printk(KERN_WARNING "dev_ip_addr - device not assigned an "
786 "IP address\n"); 776 "IP address\n");
787 return; 777 return;
788 } 778 }
789 addr = in->ifa_address; 779 memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
790 sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
791 (addr >> 16) & 0xff, addr >> 24);
792 if(bin_buf){
793 bin_buf[0] = addr & 0xff;
794 bin_buf[1] = (addr >> 8) & 0xff;
795 bin_buf[2] = (addr >> 16) & 0xff;
796 bin_buf[3] = addr >> 24;
797 }
798} 780}
799 781
800void set_ether_mac(void *d, unsigned char *addr) 782void set_ether_mac(void *d, unsigned char *addr)
@@ -829,14 +811,8 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
829 if(ip == NULL) return; 811 if(ip == NULL) return;
830 in = ip->ifa_list; 812 in = ip->ifa_list;
831 while(in != NULL){ 813 while(in != NULL){
832 address[0] = in->ifa_address & 0xff; 814 memcpy(address, &in->ifa_address, sizeof(address));
833 address[1] = (in->ifa_address >> 8) & 0xff; 815 memcpy(netmask, &in->ifa_mask, sizeof(netmask));
834 address[2] = (in->ifa_address >> 16) & 0xff;
835 address[3] = in->ifa_address >> 24;
836 netmask[0] = in->ifa_mask & 0xff;
837 netmask[1] = (in->ifa_mask >> 8) & 0xff;
838 netmask[2] = (in->ifa_mask >> 16) & 0xff;
839 netmask[3] = in->ifa_mask >> 24;
840 (*cb)(address, netmask, arg); 816 (*cb)(address, netmask, arg);
841 in = in->ifa_next; 817 in = in->ifa_next;
842 } 818 }
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 3730d4f12713..098fa65981ab 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -16,7 +16,6 @@
16#include "user_util.h" 16#include "user_util.h"
17#include "kern_util.h" 17#include "kern_util.h"
18#include "net_user.h" 18#include "net_user.h"
19#include "helper.h"
20#include "os.h" 19#include "os.h"
21 20
22int tap_open_common(void *dev, char *gate_addr) 21int tap_open_common(void *dev, char *gate_addr)
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 14dd2002d2da..ed4a1a6c5d83 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -18,7 +18,6 @@
18#include "user.h" 18#include "user.h"
19#include "chan_user.h" 19#include "chan_user.h"
20#include "port.h" 20#include "port.h"
21#include "helper.h"
22#include "os.h" 21#include "os.h"
23 22
24struct port_chan { 23struct port_chan {
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index f9e22198e011..ba471f5864a6 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -58,10 +58,8 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
58 if (filp->f_flags & O_NONBLOCK) 58 if (filp->f_flags & O_NONBLOCK)
59 return ret ? : -EAGAIN; 59 return ret ? : -EAGAIN;
60 60
61 if(need_resched()){ 61 if(need_resched())
62 current->state = TASK_INTERRUPTIBLE; 62 schedule_timeout_interruptible(1);
63 schedule_timeout(1);
64 }
65 } 63 }
66 else return n; 64 else return n;
67 if (signal_pending (current)) 65 if (signal_pending (current))
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 71af444e591f..89fbec185cc1 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -14,7 +14,6 @@
14#include "net_user.h" 14#include "net_user.h"
15#include "slip.h" 15#include "slip.h"
16#include "slip_common.h" 16#include "slip_common.h"
17#include "helper.h"
18#include "os.h" 17#include "os.h"
19 18
20void slip_user_init(void *data, void *dev) 19void slip_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 8d91f663d82c..b94c66114bc8 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -13,7 +13,6 @@
13#include "net_user.h" 13#include "net_user.h"
14#include "slirp.h" 14#include "slirp.h"
15#include "slip_common.h" 15#include "slip_common.h"
16#include "helper.h"
17#include "os.h" 16#include "os.h"
18 17
19void slirp_user_init(void *data, void *dev) 18void slirp_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 90e0e5ff451e..b530f1a6540d 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -14,7 +14,6 @@
14#include <sys/socket.h> 14#include <sys/socket.h>
15#include "kern_util.h" 15#include "kern_util.h"
16#include "chan_user.h" 16#include "chan_user.h"
17#include "helper.h"
18#include "user_util.h" 17#include "user_util.h"
19#include "user.h" 18#include "user.h"
20#include "os.h" 19#include "os.h"
diff --git a/arch/um/include/helper.h b/arch/um/include/helper.h
deleted file mode 100644
index 162ac31192fd..000000000000
--- a/arch/um/include/helper.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __HELPER_H__
7#define __HELPER_H__
8
9extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
10 unsigned long *stack_out);
11extern int run_helper_thread(int (*proc)(void *), void *arg,
12 unsigned int flags, unsigned long *stack_out,
13 int stack_order);
14extern int helper_wait(int pid);
15
16#endif
17
18/*
19 * Overrides for Emacs so that we follow Linus's tabbing style.
20 * Emacs will notice this stuff at the end of the file and automatically
21 * adjust the settings for this buffer only. This must remain at the end
22 * of the file.
23 * ---------------------------------------------------------------------------
24 * Local variables:
25 * c-file-style: "linux"
26 * End:
27 */
diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
index 9fef4123a65a..a1064c5823bf 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -57,7 +57,7 @@ extern int init_maps(unsigned long physmem, unsigned long iomem,
57 unsigned long highmem); 57 unsigned long highmem);
58extern unsigned long get_vm(unsigned long len); 58extern unsigned long get_vm(unsigned long len);
59extern void setup_physmem(unsigned long start, unsigned long usable, 59extern void setup_physmem(unsigned long start, unsigned long usable,
60 unsigned long len, unsigned long highmem); 60 unsigned long len, unsigned long long highmem);
61extern void add_iomem(char *name, int fd, unsigned long size); 61extern void add_iomem(char *name, int fd, unsigned long size);
62extern unsigned long phys_offset(unsigned long phys); 62extern unsigned long phys_offset(unsigned long phys);
63extern void unmap_physmem(void); 63extern void unmap_physmem(void);
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 89885a77a771..800c403920bc 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -25,7 +25,7 @@ struct net_user_info {
25}; 25};
26 26
27extern void ether_user_init(void *data, void *dev); 27extern void ether_user_init(void *data, void *dev);
28extern void dev_ip_addr(void *d, char *buf, char *bin_buf); 28extern void dev_ip_addr(void *d, unsigned char *bin_buf);
29extern void set_ether_mac(void *d, unsigned char *addr); 29extern void set_ether_mac(void *d, unsigned char *addr);
30extern void iter_addresses(void *d, void (*cb)(unsigned char *, 30extern void iter_addresses(void *d, void (*cb)(unsigned char *,
31 unsigned char *, void *), 31 unsigned char *, void *),
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2e58e304b8be..2cccfa5b8ab5 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -167,7 +167,7 @@ extern int can_do_skas(void);
167#endif 167#endif
168 168
169/* mem.c */ 169/* mem.c */
170extern int create_mem_file(unsigned long len); 170extern int create_mem_file(unsigned long long len);
171 171
172/* process.c */ 172/* process.c */
173extern unsigned long os_process_pc(int pid); 173extern unsigned long os_process_pc(int pid);
@@ -199,6 +199,20 @@ extern void forward_pending_sigio(int target);
199extern int start_fork_tramp(void *arg, unsigned long temp_stack, 199extern int start_fork_tramp(void *arg, unsigned long temp_stack,
200 int clone_flags, int (*tramp)(void *)); 200 int clone_flags, int (*tramp)(void *));
201 201
202/* uaccess.c */
203extern unsigned long __do_user_copy(void *to, const void *from, int n,
204 void **fault_addr, void **fault_catcher,
205 void (*op)(void *to, const void *from,
206 int n), int *faulted_out);
207
208/* helper.c */
209extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
210 unsigned long *stack_out);
211extern int run_helper_thread(int (*proc)(void *), void *arg,
212 unsigned int flags, unsigned long *stack_out,
213 int stack_order);
214extern int helper_wait(int pid);
215
202#endif 216#endif
203 217
204/* 218/*
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
index d3699fe1c613..a49ceb199ee5 100644
--- a/arch/um/include/sysdep-i386/stub.h
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -16,45 +16,69 @@ extern void stub_clone_handler(void);
16#define STUB_MMAP_NR __NR_mmap2 16#define STUB_MMAP_NR __NR_mmap2
17#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT) 17#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
18 18
19static inline long stub_syscall1(long syscall, long arg1)
20{
21 long ret;
22
23 __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1));
24
25 return ret;
26}
27
19static inline long stub_syscall2(long syscall, long arg1, long arg2) 28static inline long stub_syscall2(long syscall, long arg1, long arg2)
20{ 29{
21 long ret; 30 long ret;
22 31
23 __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx"); 32 __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
24 __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx"); 33 "c" (arg2));
25 __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax"); 34
26 __asm__("int $0x80;" : : : "%eax"); 35 return ret;
27 __asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
28 return(ret);
29} 36}
30 37
31static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) 38static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
32{ 39{
33 __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx"); 40 long ret;
34 return(stub_syscall2(syscall, arg1, arg2)); 41
42 __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
43 "c" (arg2), "d" (arg3));
44
45 return ret;
35} 46}
36 47
37static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, 48static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
38 long arg4) 49 long arg4)
39{ 50{
40 __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi"); 51 long ret;
41 return(stub_syscall3(syscall, arg1, arg2, arg3)); 52
53 __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
54 "c" (arg2), "d" (arg3), "S" (arg4));
55
56 return ret;
57}
58
59static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
60 long arg4, long arg5)
61{
62 long ret;
63
64 __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
65 "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5));
66
67 return ret;
42} 68}
43 69
44static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, 70static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
45 long arg4, long arg5, long arg6) 71 long arg4, long arg5, long arg6)
46{ 72{
47 long ret; 73 long ret;
48 __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax"); 74
49 __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx"); 75 __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; "
50 __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx"); 76 "int $0x80 ; pop %%ebp"
51 __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx"); 77 : "=a" (ret)
52 __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi"); 78 : "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3),
53 __asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi"); 79 "S" (arg4), "D" (arg5), "0" (arg6));
54 __asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; " 80
55 "int $0x80; popl %%ebp ; " 81 return ret;
56 "movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
57 return(ret);
58} 82}
59 83
60static inline void trap_myself(void) 84static inline void trap_myself(void)
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
index f599058d8263..2bd6e7a97286 100644
--- a/arch/um/include/sysdep-x86_64/stub.h
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -17,37 +17,72 @@ extern void stub_clone_handler(void);
17#define STUB_MMAP_NR __NR_mmap 17#define STUB_MMAP_NR __NR_mmap
18#define MMAP_OFFSET(o) (o) 18#define MMAP_OFFSET(o) (o)
19 19
20#define __syscall_clobber "r11","rcx","memory"
21#define __syscall "syscall"
22
20static inline long stub_syscall2(long syscall, long arg1, long arg2) 23static inline long stub_syscall2(long syscall, long arg1, long arg2)
21{ 24{
22 long ret; 25 long ret;
23 26
24 __asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi"); 27 __asm__ volatile (__syscall
25 __asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi"); 28 : "=a" (ret)
26 __asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax"); 29 : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber );
27 __asm__("syscall;" : : : "%rax", "%r11", "%rcx"); 30
28 __asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :); 31 return ret;
29 return(ret);
30} 32}
31 33
32static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) 34static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
33{ 35{
34 __asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx"); 36 long ret;
35 return(stub_syscall2(syscall, arg1, arg2)); 37
38 __asm__ volatile (__syscall
39 : "=a" (ret)
40 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3)
41 : __syscall_clobber );
42
43 return ret;
36} 44}
37 45
38static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, 46static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
39 long arg4) 47 long arg4)
40{ 48{
41 __asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10"); 49 long ret;
42 return(stub_syscall3(syscall, arg1, arg2, arg3)); 50
51 __asm__ volatile ("movq %5,%%r10 ; " __syscall
52 : "=a" (ret)
53 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
54 "g" (arg4)
55 : __syscall_clobber, "r10" );
56
57 return ret;
58}
59
60static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
61 long arg4, long arg5)
62{
63 long ret;
64
65 __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall
66 : "=a" (ret)
67 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
68 "g" (arg4), "g" (arg5)
69 : __syscall_clobber, "r10", "r8" );
70
71 return ret;
43} 72}
44 73
45static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, 74static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
46 long arg4, long arg5, long arg6) 75 long arg4, long arg5, long arg6)
47{ 76{
48 __asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9"); 77 long ret;
49 __asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8"); 78
50 return(stub_syscall4(syscall, arg1, arg2, arg3, arg4)); 79 __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; "
80 "movq %7, %%r9; " __syscall : "=a" (ret)
81 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
82 "g" (arg4), "g" (arg5), "g" (arg6)
83 : __syscall_clobber, "r10", "r8", "r9" );
84
85 return ret;
51} 86}
52 87
53static inline void trap_myself(void) 88static inline void trap_myself(void)
diff --git a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
index f77eb6428453..c0df11d06f5e 100644
--- a/arch/um/include/uml_uaccess.h
+++ b/arch/um/include/uml_uaccess.h
@@ -8,10 +8,6 @@
8 8
9extern int __do_copy_to_user(void *to, const void *from, int n, 9extern int __do_copy_to_user(void *to, const void *from, int n,
10 void **fault_addr, void **fault_catcher); 10 void **fault_addr, void **fault_catcher);
11extern unsigned long __do_user_copy(void *to, const void *from, int n,
12 void **fault_addr, void **fault_catcher,
13 void (*op)(void *to, const void *from,
14 int n), int *faulted_out);
15void __do_copy(void *to, const void *from, int n); 11void __do_copy(void *to, const void *from, int n);
16 12
17#endif 13#endif
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 1a0001b3850c..3de9d21e36bf 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,10 +7,10 @@ extra-y := vmlinux.lds
7clean-files := 7clean-files :=
8 8
9obj-y = config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec_kern.o exitcode.o \
10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.o \ 10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ 11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ 12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
13 time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \ 13 time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \
14 umid.o user_util.o 14 umid.o user_util.o
15 15
16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
@@ -24,8 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
24 24
25user-objs-$(CONFIG_TTY_LOG) += tty_log.o 25user-objs-$(CONFIG_TTY_LOG) += tty_log.o
26 26
27USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \ 27USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o
28 user_util.o
29 28
30include arch/um/scripts/Makefile.rules 29include arch/um/scripts/Makefile.rules
31 30
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index a97a72e516aa..7713e7a6f476 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -20,7 +20,6 @@
20#include "user_util.h" 20#include "user_util.h"
21#include "mem_user.h" 21#include "mem_user.h"
22#include "os.h" 22#include "os.h"
23#include "helper.h"
24 23
25EXPORT_SYMBOL(stop); 24EXPORT_SYMBOL(stop);
26EXPORT_SYMBOL(uml_physmem); 25EXPORT_SYMBOL(uml_physmem);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 462cc9d65386..fa4f915be5c5 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -234,8 +234,8 @@ void paging_init(void)
234 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 234 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
235 for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 235 for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
236 zones_size[i] = 0; 236 zones_size[i] = 0;
237 zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT); 237 zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
238 zones_size[2] = highmem >> PAGE_SHIFT; 238 zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
239 free_area_init(zones_size); 239 free_area_init(zones_size);
240 240
241 /* 241 /*
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index ea670fcc8af5..f3b583a878a6 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -246,7 +246,7 @@ int is_remapped(void *virt)
246/* Changed during early boot */ 246/* Changed during early boot */
247unsigned long high_physmem; 247unsigned long high_physmem;
248 248
249extern unsigned long physmem_size; 249extern unsigned long long physmem_size;
250 250
251int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem) 251int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
252{ 252{
@@ -321,7 +321,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
321extern int __syscall_stub_start, __binary_start; 321extern int __syscall_stub_start, __binary_start;
322 322
323void setup_physmem(unsigned long start, unsigned long reserve_end, 323void setup_physmem(unsigned long start, unsigned long reserve_end,
324 unsigned long len, unsigned long highmem) 324 unsigned long len, unsigned long long highmem)
325{ 325{
326 unsigned long reserve = reserve_end - start; 326 unsigned long reserve = reserve_end - start;
327 int pfn = PFN_UP(__pa(reserve_end)); 327 int pfn = PFN_UP(__pa(reserve_end));
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 71af4d503899..98e09395c093 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -43,53 +43,10 @@ void ptrace_disable(struct task_struct *child)
43extern int peek_user(struct task_struct * child, long addr, long data); 43extern int peek_user(struct task_struct * child, long addr, long data);
44extern int poke_user(struct task_struct * child, long addr, long data); 44extern int poke_user(struct task_struct * child, long addr, long data);
45 45
46long sys_ptrace(long request, long pid, long addr, long data) 46long arch_ptrace(struct task_struct *child, long request, long addr, long data)
47{ 47{
48 struct task_struct *child;
49 int i, ret; 48 int i, ret;
50 49
51 lock_kernel();
52 ret = -EPERM;
53 if (request == PTRACE_TRACEME) {
54 /* are we already being traced? */
55 if (current->ptrace & PT_PTRACED)
56 goto out;
57
58 ret = security_ptrace(current->parent, current);
59 if (ret)
60 goto out;
61
62 /* set the ptrace bit in the process flags. */
63 current->ptrace |= PT_PTRACED;
64 ret = 0;
65 goto out;
66 }
67 ret = -ESRCH;
68 read_lock(&tasklist_lock);
69 child = find_task_by_pid(pid);
70 if (child)
71 get_task_struct(child);
72 read_unlock(&tasklist_lock);
73 if (!child)
74 goto out;
75
76 ret = -EPERM;
77 if (pid == 1) /* you may not mess with init */
78 goto out_tsk;
79
80 if (request == PTRACE_ATTACH) {
81 ret = ptrace_attach(child);
82 goto out_tsk;
83 }
84
85#ifdef SUBACH_PTRACE_SPECIAL
86 SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
87#endif
88
89 ret = ptrace_check_attach(child, request == PTRACE_KILL);
90 if (ret < 0)
91 goto out_tsk;
92
93 switch (request) { 50 switch (request) {
94 /* when I and D space are separate, these will need to be fixed. */ 51 /* when I and D space are separate, these will need to be fixed. */
95 case PTRACE_PEEKTEXT: /* read word at location addr. */ 52 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -282,10 +239,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
282 ret = ptrace_request(child, request, addr, data); 239 ret = ptrace_request(child, request, addr, data);
283 break; 240 break;
284 } 241 }
285 out_tsk: 242
286 put_task_struct(child);
287 out:
288 unlock_kernel();
289 return ret; 243 return ret;
290} 244}
291 245
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index a52751108aa1..48b1f644b9a6 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -18,7 +18,6 @@
18#include "kern_util.h" 18#include "kern_util.h"
19#include "user_util.h" 19#include "user_util.h"
20#include "sigio.h" 20#include "sigio.h"
21#include "helper.h"
22#include "os.h" 21#include "os.h"
23 22
24/* Changed during early boot */ 23/* Changed during early boot */
@@ -225,7 +224,7 @@ static int need_poll(int n)
225 next_poll.used = n; 224 next_poll.used = n;
226 return(0); 225 return(0);
227 } 226 }
228 if(next_poll.poll != NULL) kfree(next_poll.poll); 227 kfree(next_poll.poll);
229 next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd)); 228 next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
230 if(next_poll.poll == NULL){ 229 if(next_poll.poll == NULL){
231 printk("need_poll : failed to allocate new pollfds\n"); 230 printk("need_poll : failed to allocate new pollfds\n");
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
index 09536f81ee42..44110c521e49 100644
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ b/arch/um/kernel/skas/include/mmu-skas.h
@@ -8,6 +8,7 @@
8 8
9#include "linux/config.h" 9#include "linux/config.h"
10#include "mm_id.h" 10#include "mm_id.h"
11#include "asm/ldt.h"
11 12
12struct mmu_context_skas { 13struct mmu_context_skas {
13 struct mm_id id; 14 struct mm_id id;
@@ -15,6 +16,7 @@ struct mmu_context_skas {
15#ifdef CONFIG_3_LEVEL_PGTABLES 16#ifdef CONFIG_3_LEVEL_PGTABLES
16 unsigned long last_pmd; 17 unsigned long last_pmd;
17#endif 18#endif
19 uml_ldt_t ldt;
18}; 20};
19 21
20extern void switch_mm_skas(struct mm_id * mm_idp); 22extern void switch_mm_skas(struct mm_id * mm_idp);
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index 060934740f9f..daa2f85b684c 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -10,7 +10,8 @@
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11 11
12extern int userspace_pid[]; 12extern int userspace_pid[];
13extern int proc_mm, ptrace_faultinfo; 13extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
14extern int skas_needs_stub;
14 15
15extern void switch_threads(void *me, void *next); 16extern void switch_threads(void *me, void *next);
16extern void thread_wait(void *sw, void *fb); 17extern void thread_wait(void *sw, void *fb);
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 147466d7ff4f..88ab96c609ce 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -20,7 +20,7 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
20 *task_size_out = CONFIG_HOST_TASK_SIZE; 20 *task_size_out = CONFIG_HOST_TASK_SIZE;
21#else 21#else
22 *host_size_out = top; 22 *host_size_out = top;
23 if (proc_mm && ptrace_faultinfo) 23 if (!skas_needs_stub)
24 *task_size_out = top; 24 *task_size_out = top;
25 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; 25 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
26#endif 26#endif
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 9e5e39cea821..677871f1b37c 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -15,6 +15,7 @@
15#include "asm/mmu.h" 15#include "asm/mmu.h"
16#include "asm/pgalloc.h" 16#include "asm/pgalloc.h"
17#include "asm/pgtable.h" 17#include "asm/pgtable.h"
18#include "asm/ldt.h"
18#include "os.h" 19#include "os.h"
19#include "skas.h" 20#include "skas.h"
20 21
@@ -74,13 +75,12 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
74 75
75int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) 76int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
76{ 77{
77 struct mm_struct *cur_mm = current->mm; 78 struct mmu_context_skas *from_mm = NULL;
78 struct mm_id *cur_mm_id = &cur_mm->context.skas.id; 79 struct mmu_context_skas *to_mm = &mm->context.skas;
79 struct mm_id *mm_id = &mm->context.skas.id;
80 unsigned long stack = 0; 80 unsigned long stack = 0;
81 int from, ret = -ENOMEM; 81 int from_fd, ret = -ENOMEM;
82 82
83 if(!proc_mm || !ptrace_faultinfo){ 83 if(skas_needs_stub){
84 stack = get_zeroed_page(GFP_KERNEL); 84 stack = get_zeroed_page(GFP_KERNEL);
85 if(stack == 0) 85 if(stack == 0)
86 goto out; 86 goto out;
@@ -102,33 +102,43 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
102 102
103 mm->nr_ptes--; 103 mm->nr_ptes--;
104 } 104 }
105 mm_id->stack = stack; 105
106 to_mm->id.stack = stack;
107 if(current->mm != NULL && current->mm != &init_mm)
108 from_mm = &current->mm->context.skas;
106 109
107 if(proc_mm){ 110 if(proc_mm){
108 if((cur_mm != NULL) && (cur_mm != &init_mm)) 111 if(from_mm)
109 from = cur_mm_id->u.mm_fd; 112 from_fd = from_mm->id.u.mm_fd;
110 else from = -1; 113 else from_fd = -1;
111 114
112 ret = new_mm(from, stack); 115 ret = new_mm(from_fd, stack);
113 if(ret < 0){ 116 if(ret < 0){
114 printk("init_new_context_skas - new_mm failed, " 117 printk("init_new_context_skas - new_mm failed, "
115 "errno = %d\n", ret); 118 "errno = %d\n", ret);
116 goto out_free; 119 goto out_free;
117 } 120 }
118 mm_id->u.mm_fd = ret; 121 to_mm->id.u.mm_fd = ret;
119 } 122 }
120 else { 123 else {
121 if((cur_mm != NULL) && (cur_mm != &init_mm)) 124 if(from_mm)
122 mm_id->u.pid = copy_context_skas0(stack, 125 to_mm->id.u.pid = copy_context_skas0(stack,
123 cur_mm_id->u.pid); 126 from_mm->id.u.pid);
124 else mm_id->u.pid = start_userspace(stack); 127 else to_mm->id.u.pid = start_userspace(stack);
128 }
129
130 ret = init_new_ldt(to_mm, from_mm);
131 if(ret < 0){
132 printk("init_new_context_skas - init_ldt"
133 " failed, errno = %d\n", ret);
134 goto out_free;
125 } 135 }
126 136
127 return 0; 137 return 0;
128 138
129 out_free: 139 out_free:
130 if(mm_id->stack != 0) 140 if(to_mm->id.stack != 0)
131 free_page(mm_id->stack); 141 free_page(to_mm->id.stack);
132 out: 142 out:
133 return ret; 143 return ret;
134} 144}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 5cd0e9929789..599d679bd4fc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -69,6 +69,17 @@ void wait_stub_done(int pid, int sig, char * fname)
69 69
70 if((n < 0) || !WIFSTOPPED(status) || 70 if((n < 0) || !WIFSTOPPED(status) ||
71 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ 71 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
72 unsigned long regs[FRAME_SIZE];
73 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
74 printk("Failed to get registers from stub, "
75 "errno = %d\n", errno);
76 else {
77 int i;
78
79 printk("Stub registers -\n");
80 for(i = 0; i < FRAME_SIZE; i++)
81 printk("\t%d - %lx\n", i, regs[i]);
82 }
72 panic("%s : failed to wait for SIGUSR1/SIGTRAP, " 83 panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
73 "pid = %d, n = %d, errno = %d, status = 0x%x\n", 84 "pid = %d, n = %d, errno = %d, status = 0x%x\n",
74 fname, pid, n, errno, status); 85 fname, pid, n, errno, status);
@@ -370,9 +381,9 @@ int copy_context_skas0(unsigned long new_stack, int pid)
370} 381}
371 382
372/* 383/*
373 * This is used only, if proc_mm is available, while PTRACE_FAULTINFO 384 * This is used only, if stub pages are needed, while proc_mm is
374 * isn't. Opening /proc/mm creates a new mm_context, which lacks the stub-pages 385 * availabl. Opening /proc/mm creates a new mm_context, which lacks
375 * Thus, we map them using /proc/mm-fd 386 * the stub-pages. Thus, we map them using /proc/mm-fd
376 */ 387 */
377void map_stub_pages(int fd, unsigned long code, 388void map_stub_pages(int fd, unsigned long code,
378 unsigned long data, unsigned long stack) 389 unsigned long data, unsigned long stack)
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index efe92e8aa2a9..9c990253966c 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -145,7 +145,7 @@ int new_mm(int from, unsigned long stack)
145 "err = %d\n", -n); 145 "err = %d\n", -n);
146 } 146 }
147 147
148 if(!ptrace_faultinfo) 148 if(skas_needs_stub)
149 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); 149 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
150 150
151 return(fd); 151 return(fd);
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index 8c220f054b61..6c92bbccb49c 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -10,6 +10,7 @@
10#include "uml_uaccess.h" 10#include "uml_uaccess.h"
11#include "task.h" 11#include "task.h"
12#include "kern_util.h" 12#include "kern_util.h"
13#include "os.h"
13 14
14int __do_copy_from_user(void *to, const void *from, int n, 15int __do_copy_from_user(void *to, const void *from, int n,
15 void **fault_addr, void **fault_catcher) 16 void **fault_addr, void **fault_catcher)
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
new file mode 100644
index 000000000000..054e3de0784e
--- /dev/null
+++ b/arch/um/kernel/uaccess.c
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4 * Licensed under the GPL
5 */
6
7/* These are here rather than tt/uaccess.c because skas mode needs them in
8 * order to do SIGBUS recovery when a tmpfs mount runs out of room.
9 */
10
11#include <linux/string.h>
12#include "os.h"
13
14void __do_copy(void *to, const void *from, int n)
15{
16 memcpy(to, from, n);
17}
18
19
20int __do_copy_to_user(void *to, const void *from, int n,
21 void **fault_addr, void **fault_catcher)
22{
23 unsigned long fault;
24 int faulted;
25
26 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
27 __do_copy, &faulted);
28 if(!faulted) return(0);
29 else return(n - (fault - (unsigned long) to));
30}
diff --git a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
deleted file mode 100644
index d035257ed0af..000000000000
--- a/arch/um/kernel/uaccess_user.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4 * Licensed under the GPL
5 */
6
7#include <setjmp.h>
8#include <string.h>
9
10/* These are here rather than tt/uaccess.c because skas mode needs them in
11 * order to do SIGBUS recovery when a tmpfs mount runs out of room.
12 */
13
14unsigned long __do_user_copy(void *to, const void *from, int n,
15 void **fault_addr, void **fault_catcher,
16 void (*op)(void *to, const void *from,
17 int n), int *faulted_out)
18{
19 unsigned long *faddrp = (unsigned long *) fault_addr, ret;
20
21 sigjmp_buf jbuf;
22 *fault_catcher = &jbuf;
23 if(sigsetjmp(jbuf, 1) == 0){
24 (*op)(to, from, n);
25 ret = 0;
26 *faulted_out = 0;
27 }
28 else {
29 ret = *faddrp;
30 *faulted_out = 1;
31 }
32 *fault_addr = NULL;
33 *fault_catcher = NULL;
34 return ret;
35}
36
37void __do_copy(void *to, const void *from, int n)
38{
39 memcpy(to, from, n);
40}
41
42
43int __do_copy_to_user(void *to, const void *from, int n,
44 void **fault_addr, void **fault_catcher)
45{
46 unsigned long fault;
47 int faulted;
48
49 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
50 __do_copy, &faulted);
51 if(!faulted) return(0);
52 else return(n - (fault - (unsigned long) to));
53}
54
55/*
56 * Overrides for Emacs so that we follow Linus's tabbing style.
57 * Emacs will notice this stuff at the end of the file and automatically
58 * adjust the settings for this buffer only. This must remain at the end
59 * of the file.
60 * ---------------------------------------------------------------------------
61 * Local variables:
62 * c-file-style: "linux"
63 * End:
64 */
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 93dc782dc1cc..142a9493912b 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -137,7 +137,7 @@ static char *argv1_end = NULL;
137 137
138/* Set in early boot */ 138/* Set in early boot */
139static int have_root __initdata = 0; 139static int have_root __initdata = 0;
140long physmem_size = 32 * 1024 * 1024; 140long long physmem_size = 32 * 1024 * 1024;
141 141
142void set_cmdline(char *cmd) 142void set_cmdline(char *cmd)
143{ 143{
@@ -402,7 +402,7 @@ int linux_main(int argc, char **argv)
402#ifndef CONFIG_HIGHMEM 402#ifndef CONFIG_HIGHMEM
403 highmem = 0; 403 highmem = 0;
404 printf("CONFIG_HIGHMEM not enabled - physical memory shrunk " 404 printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
405 "to %ld bytes\n", physmem_size); 405 "to %lu bytes\n", physmem_size);
406#endif 406#endif
407 } 407 }
408 408
@@ -414,8 +414,8 @@ int linux_main(int argc, char **argv)
414 414
415 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); 415 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
416 if(init_maps(physmem_size, iomem_size, highmem)){ 416 if(init_maps(physmem_size, iomem_size, highmem)){
417 printf("Failed to allocate mem_map for %ld bytes of physical " 417 printf("Failed to allocate mem_map for %lu bytes of physical "
418 "memory and %ld bytes of highmem\n", physmem_size, 418 "memory and %lu bytes of highmem\n", physmem_size,
419 highmem); 419 highmem);
420 exit(1); 420 exit(1);
421 } 421 }
@@ -426,7 +426,7 @@ int linux_main(int argc, char **argv)
426 end_vm = start_vm + virtmem_size; 426 end_vm = start_vm + virtmem_size;
427 427
428 if(virtmem_size < physmem_size) 428 if(virtmem_size < physmem_size)
429 printf("Kernel virtual memory size shrunk to %ld bytes\n", 429 printf("Kernel virtual memory size shrunk to %lu bytes\n",
430 virtmem_size); 430 virtmem_size);
431 431
432 uml_postsetup(); 432 uml_postsetup();
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
index 41d17c71511c..4c231161f257 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/kernel/user_util.c
@@ -27,7 +27,6 @@
27#include "user.h" 27#include "user.h"
28#include "mem_user.h" 28#include "mem_user.h"
29#include "init.h" 29#include "init.h"
30#include "helper.h"
31#include "ptrace_user.h" 30#include "ptrace_user.h"
32#include "uml-config.h" 31#include "uml-config.h"
33 32
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index d15ec2af6a22..b83ac8e21c35 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,11 +3,12 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o time.o \ 6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
7 tt.o tty.o user_syms.o drivers/ sys-$(SUBARCH)/ 7 start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \
8 sys-$(SUBARCH)/
8 9
9USER_OBJS := aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o \ 10USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
10 time.o tt.o tty.o 11 start_up.o time.o tt.o tty.o uaccess.o
11 12
12elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 13elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
13CFLAGS_elf_aux.o += -I$(objtree)/arch/um 14CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 41cfb0944201..ffa759addd3c 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -10,7 +10,6 @@
10#include <sched.h> 10#include <sched.h>
11#include <sys/syscall.h> 11#include <sys/syscall.h>
12#include "os.h" 12#include "os.h"
13#include "helper.h"
14#include "aio.h" 13#include "aio.h"
15#include "init.h" 14#include "init.h"
16#include "user.h" 15#include "user.h"
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index cd4d6544da71..901b85e8a1c6 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -19,7 +19,6 @@
19#include "user_util.h" 19#include "user_util.h"
20#include "net_user.h" 20#include "net_user.h"
21#include "etap.h" 21#include "etap.h"
22#include "helper.h"
23#include "os.h" 22#include "os.h"
24 23
25#define MAX_PACKET ETH_MAX_PACKET 24#define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 4ba9b17adf13..52945338b64d 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -20,7 +20,6 @@
20#include "kern_util.h" 20#include "kern_util.h"
21#include "user_util.h" 21#include "user_util.h"
22#include "user.h" 22#include "user.h"
23#include "helper.h"
24#include "os.h" 23#include "os.h"
25 24
26#define MAX_PACKET ETH_MAX_PACKET 25#define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/kernel/helper.c b/arch/um/os-Linux/helper.c
index 33fb0bd3b11a..36cc8475bcda 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -13,7 +13,6 @@
13#include "user.h" 13#include "user.h"
14#include "kern_util.h" 14#include "kern_util.h"
15#include "user_util.h" 15#include "user_util.h"
16#include "helper.h"
17#include "os.h" 16#include "os.h"
18 17
19struct helper_data { 18struct helper_data {
@@ -46,7 +45,7 @@ static int helper_child(void *arg)
46 errval = errno; 45 errval = errno;
47 printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); 46 printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
48 os_write_file(data->fd, &errval, sizeof(errval)); 47 os_write_file(data->fd, &errval, sizeof(errval));
49 os_kill_process(os_getpid(), 0); 48 kill(os_getpid(), SIGKILL);
50 return(0); 49 return(0);
51} 50}
52 51
@@ -90,7 +89,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
90 goto out_close; 89 goto out_close;
91 } 90 }
92 91
93 os_close_file(fds[1]); 92 close(fds[1]);
94 fds[1] = -1; 93 fds[1] = -1;
95 94
96 /*Read the errno value from the child.*/ 95 /*Read the errno value from the child.*/
@@ -98,7 +97,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
98 if(n < 0){ 97 if(n < 0){
99 printk("run_helper : read on pipe failed, ret = %d\n", -n); 98 printk("run_helper : read on pipe failed, ret = %d\n", -n);
100 ret = n; 99 ret = n;
101 os_kill_process(pid, 1); 100 kill(pid, SIGKILL);
101 CATCH_EINTR(waitpid(pid, NULL, 0));
102 } 102 }
103 else if(n != 0){ 103 else if(n != 0){
104 CATCH_EINTR(n = waitpid(pid, NULL, 0)); 104 CATCH_EINTR(n = waitpid(pid, NULL, 0));
@@ -109,8 +109,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
109 109
110out_close: 110out_close:
111 if (fds[1] != -1) 111 if (fds[1] != -1)
112 os_close_file(fds[1]); 112 close(fds[1]);
113 os_close_file(fds[0]); 113 close(fds[0]);
114out_free: 114out_free:
115 if(stack_out == NULL) 115 if(stack_out == NULL)
116 free_stack(stack, 0); 116 free_stack(stack, 0);
@@ -118,7 +118,7 @@ out_free:
118 return(ret); 118 return(ret);
119} 119}
120 120
121int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 121int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
122 unsigned long *stack_out, int stack_order) 122 unsigned long *stack_out, int stack_order)
123{ 123{
124 unsigned long stack, sp; 124 unsigned long stack, sp;
@@ -131,7 +131,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
131 pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); 131 pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
132 if(pid < 0){ 132 if(pid < 0){
133 err = -errno; 133 err = -errno;
134 printk("run_helper_thread : clone failed, errno = %d\n", 134 printk("run_helper_thread : clone failed, errno = %d\n",
135 errno); 135 errno);
136 return err; 136 return err;
137 } 137 }
diff --git a/arch/um/kernel/main.c b/arch/um/os-Linux/main.c
index d31027f0fe39..23da27d22569 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/os-Linux/main.c
@@ -157,25 +157,25 @@ int main(int argc, char **argv, char **envp)
157 */ 157 */
158 change_sig(SIGPROF, 0); 158 change_sig(SIGPROF, 0);
159 159
160 /* This signal stuff used to be in the reboot case. However, 160 /* This signal stuff used to be in the reboot case. However,
161 * sometimes a SIGVTALRM can come in when we're halting (reproducably 161 * sometimes a SIGVTALRM can come in when we're halting (reproducably
162 * when writing out gcov information, presumably because that takes 162 * when writing out gcov information, presumably because that takes
163 * some time) and cause a segfault. 163 * some time) and cause a segfault.
164 */ 164 */
165 165
166 /* stop timers and set SIG*ALRM to be ignored */ 166 /* stop timers and set SIG*ALRM to be ignored */
167 disable_timer(); 167 disable_timer();
168 168
169 /* disable SIGIO for the fds and set SIGIO to be ignored */ 169 /* disable SIGIO for the fds and set SIGIO to be ignored */
170 err = deactivate_all_fds(); 170 err = deactivate_all_fds();
171 if(err) 171 if(err)
172 printf("deactivate_all_fds failed, errno = %d\n", -err); 172 printf("deactivate_all_fds failed, errno = %d\n", -err);
173 173
174 /* Let any pending signals fire now. This ensures 174 /* Let any pending signals fire now. This ensures
175 * that they won't be delivered after the exec, when 175 * that they won't be delivered after the exec, when
176 * they are definitely not expected. 176 * they are definitely not expected.
177 */ 177 */
178 unblock_signals(); 178 unblock_signals();
179 179
180 /* Reboot */ 180 /* Reboot */
181 if(ret){ 181 if(ret){
@@ -257,14 +257,3 @@ void __wrap_free(void *ptr)
257 } 257 }
258 else __real_free(ptr); 258 else __real_free(ptr);
259} 259}
260
261/*
262 * Overrides for Emacs so that we follow Linus's tabbing style.
263 * Emacs will notice this stuff at the end of the file and automatically
264 * adjust the settings for this buffer only. This must remain at the end
265 * of the file.
266 * ---------------------------------------------------------------------------
267 * Local variables:
268 * c-file-style: "linux"
269 * End:
270 */
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 8e71edaaf80b..9d7d69a523bb 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -88,7 +88,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink)
88 * This proc is used in start_up.c 88 * This proc is used in start_up.c
89 * So it isn't 'static'. 89 * So it isn't 'static'.
90 */ 90 */
91int create_tmp_file(unsigned long len) 91int create_tmp_file(unsigned long long len)
92{ 92{
93 int fd, err; 93 int fd, err;
94 char zero; 94 char zero;
@@ -121,7 +121,7 @@ int create_tmp_file(unsigned long len)
121 return(fd); 121 return(fd);
122} 122}
123 123
124static int create_anon_file(unsigned long len) 124static int create_anon_file(unsigned long long len)
125{ 125{
126 void *addr; 126 void *addr;
127 int fd; 127 int fd;
@@ -144,7 +144,7 @@ static int create_anon_file(unsigned long len)
144 144
145extern int have_devanon; 145extern int have_devanon;
146 146
147int create_mem_file(unsigned long len) 147int create_mem_file(unsigned long long len)
148{ 148{
149 int err, fd; 149 int err, fd;
150 150
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b99ab414542f..37517d49c4ae 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -135,7 +135,9 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
135} 135}
136 136
137int ptrace_faultinfo = 1; 137int ptrace_faultinfo = 1;
138int ptrace_ldt = 1;
138int proc_mm = 1; 139int proc_mm = 1;
140int skas_needs_stub = 0;
139 141
140static int __init skas0_cmd_param(char *str, int* add) 142static int __init skas0_cmd_param(char *str, int* add)
141{ 143{
@@ -294,7 +296,7 @@ static void __init check_ptrace(void)
294 check_sysemu(); 296 check_sysemu();
295} 297}
296 298
297extern int create_tmp_file(unsigned long len); 299extern int create_tmp_file(unsigned long long len);
298 300
299static void check_tmpexec(void) 301static void check_tmpexec(void)
300{ 302{
@@ -352,14 +354,26 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
352" it. To support PTRACE_FAULTINFO, the host needs to be patched\n" 354" it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
353" using the current skas3 patch.\n\n"); 355" using the current skas3 patch.\n\n");
354 356
357static int __init noptraceldt_cmd_param(char *str, int* add)
358{
359 ptrace_ldt = 0;
360 return 0;
361}
362
363__uml_setup("noptraceldt", noptraceldt_cmd_param,
364"noptraceldt\n"
365" Turns off usage of PTRACE_LDT, even if host supports it.\n"
366" To support PTRACE_LDT, the host needs to be patched using\n"
367" the current skas3 patch.\n\n");
368
355#ifdef UML_CONFIG_MODE_SKAS 369#ifdef UML_CONFIG_MODE_SKAS
356static inline void check_skas3_ptrace_support(void) 370static inline void check_skas3_ptrace_faultinfo(void)
357{ 371{
358 struct ptrace_faultinfo fi; 372 struct ptrace_faultinfo fi;
359 void *stack; 373 void *stack;
360 int pid, n; 374 int pid, n;
361 375
362 printf("Checking for the skas3 patch in the host..."); 376 printf(" - PTRACE_FAULTINFO...");
363 pid = start_ptraced_child(&stack); 377 pid = start_ptraced_child(&stack);
364 378
365 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 379 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
@@ -381,9 +395,49 @@ static inline void check_skas3_ptrace_support(void)
381 stop_ptraced_child(pid, stack, 1, 1); 395 stop_ptraced_child(pid, stack, 1, 1);
382} 396}
383 397
384int can_do_skas(void) 398static inline void check_skas3_ptrace_ldt(void)
399{
400#ifdef PTRACE_LDT
401 void *stack;
402 int pid, n;
403 unsigned char ldtbuf[40];
404 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
405 .func = 2, /* read default ldt */
406 .ptr = ldtbuf,
407 .bytecount = sizeof(ldtbuf)};
408
409 printf(" - PTRACE_LDT...");
410 pid = start_ptraced_child(&stack);
411
412 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
413 if (n < 0) {
414 if(errno == EIO)
415 printf("not found\n");
416 else {
417 perror("not found");
418 }
419 ptrace_ldt = 0;
420 }
421 else {
422 if(ptrace_ldt)
423 printf("found\n");
424 else
425 printf("found, but use is disabled\n");
426 }
427
428 stop_ptraced_child(pid, stack, 1, 1);
429#else
430 /* PTRACE_LDT might be disabled via cmdline option.
431 * We want to override this, else we might use the stub
432 * without real need
433 */
434 ptrace_ldt = 1;
435#endif
436}
437
438static inline void check_skas3_proc_mm(void)
385{ 439{
386 printf("Checking for /proc/mm..."); 440 printf(" - /proc/mm...");
387 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) { 441 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
388 proc_mm = 0; 442 proc_mm = 0;
389 printf("not found\n"); 443 printf("not found\n");
@@ -394,8 +448,19 @@ int can_do_skas(void)
394 else 448 else
395 printf("found\n"); 449 printf("found\n");
396 } 450 }
451}
452
453int can_do_skas(void)
454{
455 printf("Checking for the skas3 patch in the host:\n");
456
457 check_skas3_proc_mm();
458 check_skas3_ptrace_faultinfo();
459 check_skas3_ptrace_ldt();
460
461 if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
462 skas_needs_stub = 1;
397 463
398 check_skas3_ptrace_support();
399 return 1; 464 return 1;
400} 465}
401#else 466#else
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
new file mode 100644
index 000000000000..38d710158c3d
--- /dev/null
+++ b/arch/um/os-Linux/uaccess.c
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4 * Licensed under the GPL
5 */
6
7#include <setjmp.h>
8#include <string.h>
9
10unsigned long __do_user_copy(void *to, const void *from, int n,
11 void **fault_addr, void **fault_catcher,
12 void (*op)(void *to, const void *from,
13 int n), int *faulted_out)
14{
15 unsigned long *faddrp = (unsigned long *) fault_addr, ret;
16
17 sigjmp_buf jbuf;
18 *fault_catcher = &jbuf;
19 if(sigsetjmp(jbuf, 1) == 0){
20 (*op)(to, from, n);
21 ret = 0;
22 *faulted_out = 0;
23 }
24 else {
25 ret = *faddrp;
26 *faulted_out = 1;
27 }
28 *fault_addr = NULL;
29 *fault_catcher = NULL;
30 return ret;
31}
32
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 651d9d88b656..b3fbf125709b 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -26,8 +26,13 @@ define unprofile
26 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) 26 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
27endef 27endef
28 28
29# cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If
30# so, it's considered to be a path relative to $(srcdir) rather than
31# $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from
32# arch/um/sys-i386 rather than arch/i386 like the other borrowed files. So,
33# it sets $(ldt.c-dir) to /arch/um/sys-i386.
29quiet_cmd_make_link = SYMLINK $@ 34quiet_cmd_make_link = SYMLINK $@
30cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ 35cmd_make_link = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@
31 36
32# this needs to be before the foreach, because targets does not accept 37# this needs to be before the foreach, because targets does not accept
33# complete paths like $(obj)/$(f). To make sure this works, use a := assignment 38# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 36b5c2c13289..6360f1c958d0 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -3,53 +3,26 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/stddef.h"
6#include "linux/config.h" 7#include "linux/config.h"
7#include "linux/sched.h" 8#include "linux/sched.h"
8#include "linux/slab.h" 9#include "linux/slab.h"
9#include "linux/types.h" 10#include "linux/types.h"
11#include "linux/errno.h"
10#include "asm/uaccess.h" 12#include "asm/uaccess.h"
11#include "asm/ptrace.h"
12#include "asm/smp.h" 13#include "asm/smp.h"
13#include "asm/ldt.h" 14#include "asm/ldt.h"
15#include "asm/unistd.h"
14#include "choose-mode.h" 16#include "choose-mode.h"
15#include "kern.h" 17#include "kern.h"
16#include "mode_kern.h" 18#include "mode_kern.h"
17 19
18#ifdef CONFIG_MODE_TT
19
20extern int modify_ldt(int func, void *ptr, unsigned long bytecount); 20extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
21 21
22static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount) 22#ifdef CONFIG_MODE_TT
23{
24 return modify_ldt(func, ptr, bytecount);
25}
26
27#endif
28
29#ifdef CONFIG_MODE_SKAS
30
31#include "skas.h"
32#include "skas_ptrace.h"
33
34static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
35{
36 struct ptrace_ldt ldt;
37 u32 cpu;
38 int res;
39
40 ldt = ((struct ptrace_ldt) { .func = func,
41 .ptr = ptr,
42 .bytecount = bytecount });
43
44 cpu = get_cpu();
45 res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
46 put_cpu();
47
48 return res;
49}
50#endif
51 23
52int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) 24static long do_modify_ldt_tt(int func, void __user *ptr,
25 unsigned long bytecount)
53{ 26{
54 struct user_desc info; 27 struct user_desc info;
55 int res = 0; 28 int res = 0;
@@ -89,8 +62,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
89 goto out; 62 goto out;
90 } 63 }
91 64
92 res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, 65 res = modify_ldt(func, p, bytecount);
93 p, bytecount);
94 if(res < 0) 66 if(res < 0)
95 goto out; 67 goto out;
96 68
@@ -108,3 +80,467 @@ out:
108 kfree(buf); 80 kfree(buf);
109 return res; 81 return res;
110} 82}
83
84#endif
85
86#ifdef CONFIG_MODE_SKAS
87
88#include "skas.h"
89#include "skas_ptrace.h"
90#include "asm/mmu_context.h"
91
92long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
93 void **addr, int done)
94{
95 long res;
96
97 if(proc_mm){
98 /* This is a special handling for the case, that the mm to
99 * modify isn't current->active_mm.
100 * If this is called directly by modify_ldt,
101 * (current->active_mm->context.skas.u == mm_idp)
102 * will be true. So no call to switch_mm_skas(mm_idp) is done.
103 * If this is called in case of init_new_ldt or PTRACE_LDT,
104 * mm_idp won't belong to current->active_mm, but child->mm.
105 * So we need to switch child's mm into our userspace, then
106 * later switch back.
107 *
108 * Note: I'm unshure: should interrupts be disabled here?
109 */
110 if(!current->active_mm || current->active_mm == &init_mm ||
111 mm_idp != &current->active_mm->context.skas.id)
112 switch_mm_skas(mm_idp);
113 }
114
115 if(ptrace_ldt) {
116 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
117 .func = func,
118 .ptr = desc,
119 .bytecount = sizeof(*desc)};
120 u32 cpu;
121 int pid;
122
123 if(!proc_mm)
124 pid = mm_idp->u.pid;
125 else {
126 cpu = get_cpu();
127 pid = userspace_pid[cpu];
128 }
129
130 res = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
131 if(res)
132 res = errno;
133
134 if(proc_mm)
135 put_cpu();
136 }
137 else {
138 void *stub_addr;
139 res = syscall_stub_data(mm_idp, (unsigned long *)desc,
140 (sizeof(*desc) + sizeof(long) - 1) &
141 ~(sizeof(long) - 1),
142 addr, &stub_addr);
143 if(!res){
144 unsigned long args[] = { func,
145 (unsigned long)stub_addr,
146 sizeof(*desc),
147 0, 0, 0 };
148 res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
149 0, addr, done);
150 }
151 }
152
153 if(proc_mm){
154 /* This is the second part of special handling, that makes
155 * PTRACE_LDT possible to implement.
156 */
157 if(current->active_mm && current->active_mm != &init_mm &&
158 mm_idp != &current->active_mm->context.skas.id)
159 switch_mm_skas(&current->active_mm->context.skas.id);
160 }
161
162 return res;
163}
164
165static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
166{
167 int res, n;
168 struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
169 .func = 0,
170 .bytecount = bytecount,
171 .ptr = (void *)kmalloc(bytecount, GFP_KERNEL)};
172 u32 cpu;
173
174 if(ptrace_ldt.ptr == NULL)
175 return -ENOMEM;
176
177 /* This is called from sys_modify_ldt only, so userspace_pid gives
178 * us the right number
179 */
180
181 cpu = get_cpu();
182 res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0,
183 (unsigned long) &ptrace_ldt);
184 put_cpu();
185 if(res < 0)
186 goto out;
187
188 n = copy_to_user(ptr, ptrace_ldt.ptr, res);
189 if(n != 0)
190 res = -EFAULT;
191
192 out:
193 kfree(ptrace_ldt.ptr);
194
195 return res;
196}
197
198/*
199 * In skas mode, we hold our own ldt data in UML.
200 * Thus, the code implementing sys_modify_ldt_skas
201 * is very similar to (and mostly stolen from) sys_modify_ldt
202 * for arch/i386/kernel/ldt.c
203 * The routines copied and modified in part are:
204 * - read_ldt
205 * - read_default_ldt
206 * - write_ldt
207 * - sys_modify_ldt_skas
208 */
209
210static int read_ldt(void __user * ptr, unsigned long bytecount)
211{
212 int i, err = 0;
213 unsigned long size;
214 uml_ldt_t * ldt = &current->mm->context.skas.ldt;
215
216 if(!ldt->entry_count)
217 goto out;
218 if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
219 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
220 err = bytecount;
221
222 if(ptrace_ldt){
223 return read_ldt_from_host(ptr, bytecount);
224 }
225
226 down(&ldt->semaphore);
227 if(ldt->entry_count <= LDT_DIRECT_ENTRIES){
228 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
229 if(size > bytecount)
230 size = bytecount;
231 if(copy_to_user(ptr, ldt->entries, size))
232 err = -EFAULT;
233 bytecount -= size;
234 ptr += size;
235 }
236 else {
237 for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
238 i++){
239 size = PAGE_SIZE;
240 if(size > bytecount)
241 size = bytecount;
242 if(copy_to_user(ptr, ldt->pages[i], size)){
243 err = -EFAULT;
244 break;
245 }
246 bytecount -= size;
247 ptr += size;
248 }
249 }
250 up(&ldt->semaphore);
251
252 if(bytecount == 0 || err == -EFAULT)
253 goto out;
254
255 if(clear_user(ptr, bytecount))
256 err = -EFAULT;
257
258out:
259 return err;
260}
261
262static int read_default_ldt(void __user * ptr, unsigned long bytecount)
263{
264 int err;
265
266 if(bytecount > 5*LDT_ENTRY_SIZE)
267 bytecount = 5*LDT_ENTRY_SIZE;
268
269 err = bytecount;
270 /* UML doesn't support lcall7 and lcall27.
271 * So, we don't really have a default ldt, but emulate
272 * an empty ldt of common host default ldt size.
273 */
274 if(clear_user(ptr, bytecount))
275 err = -EFAULT;
276
277 return err;
278}
279
280static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
281{
282 uml_ldt_t * ldt = &current->mm->context.skas.ldt;
283 struct mm_id * mm_idp = &current->mm->context.skas.id;
284 int i, err;
285 struct user_desc ldt_info;
286 struct ldt_entry entry0, *ldt_p;
287 void *addr = NULL;
288
289 err = -EINVAL;
290 if(bytecount != sizeof(ldt_info))
291 goto out;
292 err = -EFAULT;
293 if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
294 goto out;
295
296 err = -EINVAL;
297 if(ldt_info.entry_number >= LDT_ENTRIES)
298 goto out;
299 if(ldt_info.contents == 3){
300 if (func == 1)
301 goto out;
302 if (ldt_info.seg_not_present == 0)
303 goto out;
304 }
305
306 if(!ptrace_ldt)
307 down(&ldt->semaphore);
308
309 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
310 if(err)
311 goto out_unlock;
312 else if(ptrace_ldt) {
313 /* With PTRACE_LDT available, this is used as a flag only */
314 ldt->entry_count = 1;
315 goto out;
316 }
317
318 if(ldt_info.entry_number >= ldt->entry_count &&
319 ldt_info.entry_number >= LDT_DIRECT_ENTRIES){
320 for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
321 i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
322 i++){
323 if(i == 0)
324 memcpy(&entry0, ldt->entries, sizeof(entry0));
325 ldt->pages[i] = (struct ldt_entry *)
326 __get_free_page(GFP_KERNEL|__GFP_ZERO);
327 if(!ldt->pages[i]){
328 err = -ENOMEM;
329 /* Undo the change in host */
330 memset(&ldt_info, 0, sizeof(ldt_info));
331 write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
332 goto out_unlock;
333 }
334 if(i == 0) {
335 memcpy(ldt->pages[0], &entry0, sizeof(entry0));
336 memcpy(ldt->pages[0]+1, ldt->entries+1,
337 sizeof(entry0)*(LDT_DIRECT_ENTRIES-1));
338 }
339 ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
340 }
341 }
342 if(ldt->entry_count <= ldt_info.entry_number)
343 ldt->entry_count = ldt_info.entry_number + 1;
344
345 if(ldt->entry_count <= LDT_DIRECT_ENTRIES)
346 ldt_p = ldt->entries + ldt_info.entry_number;
347 else
348 ldt_p = ldt->pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
349 ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
350
351 if(ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
352 (func == 1 || LDT_empty(&ldt_info))){
353 ldt_p->a = 0;
354 ldt_p->b = 0;
355 }
356 else{
357 if (func == 1)
358 ldt_info.useable = 0;
359 ldt_p->a = LDT_entry_a(&ldt_info);
360 ldt_p->b = LDT_entry_b(&ldt_info);
361 }
362 err = 0;
363
364out_unlock:
365 up(&ldt->semaphore);
366out:
367 return err;
368}
369
370static long do_modify_ldt_skas(int func, void __user *ptr,
371 unsigned long bytecount)
372{
373 int ret = -ENOSYS;
374
375 switch (func) {
376 case 0:
377 ret = read_ldt(ptr, bytecount);
378 break;
379 case 1:
380 case 0x11:
381 ret = write_ldt(ptr, bytecount, func);
382 break;
383 case 2:
384 ret = read_default_ldt(ptr, bytecount);
385 break;
386 }
387 return ret;
388}
389
390short dummy_list[9] = {0, -1};
391short * host_ldt_entries = NULL;
392
393void ldt_get_host_info(void)
394{
395 long ret;
396 struct ldt_entry * ldt;
397 int i, size, k, order;
398
399 host_ldt_entries = dummy_list+1;
400
401 for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
402
403 ldt = (struct ldt_entry *)
404 __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
405 if(ldt == NULL) {
406 printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n");
407 return;
408 }
409
410 ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
411 if(ret < 0) {
412 printk("ldt_get_host_info: couldn't read host ldt\n");
413 goto out_free;
414 }
415 if(ret == 0) {
416 /* default_ldt is active, simply write an empty entry 0 */
417 host_ldt_entries = dummy_list;
418 goto out_free;
419 }
420
421 for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){
422 if(ldt[i].a != 0 || ldt[i].b != 0)
423 size++;
424 }
425
426 if(size < sizeof(dummy_list)/sizeof(dummy_list[0])) {
427 host_ldt_entries = dummy_list;
428 }
429 else {
430 size = (size + 1) * sizeof(dummy_list[0]);
431 host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
432 if(host_ldt_entries == NULL) {
433 printk("ldt_get_host_info: couldn't allocate host ldt list\n");
434 goto out_free;
435 }
436 }
437
438 for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
439 if(ldt[i].a != 0 || ldt[i].b != 0) {
440 host_ldt_entries[k++] = i;
441 }
442 }
443 host_ldt_entries[k] = -1;
444
445out_free:
446 free_pages((unsigned long)ldt, order);
447}
448
449long init_new_ldt(struct mmu_context_skas * new_mm,
450 struct mmu_context_skas * from_mm)
451{
452 struct user_desc desc;
453 short * num_p;
454 int i;
455 long page, err=0;
456 void *addr = NULL;
457
458 memset(&desc, 0, sizeof(desc));
459
460 if(!ptrace_ldt)
461 init_MUTEX(&new_mm->ldt.semaphore);
462
463 if(!from_mm){
464 /*
465 * We have to initialize a clean ldt.
466 */
467 if(proc_mm) {
468 /*
469 * If the new mm was created using proc_mm, host's
470 * default-ldt currently is assigned, which normally
471 * contains the call-gates for lcall7 and lcall27.
472 * To remove these gates, we simply write an empty
473 * entry as number 0 to the host.
474 */
475 err = write_ldt_entry(&new_mm->id, 1, &desc,
476 &addr, 1);
477 }
478 else{
479 /*
480 * Now we try to retrieve info about the ldt, we
481 * inherited from the host. All ldt-entries found
482 * will be reset in the following loop
483 */
484 if(host_ldt_entries == NULL)
485 ldt_get_host_info();
486 for(num_p=host_ldt_entries; *num_p != -1; num_p++){
487 desc.entry_number = *num_p;
488 err = write_ldt_entry(&new_mm->id, 1, &desc,
489 &addr, *(num_p + 1) == -1);
490 if(err)
491 break;
492 }
493 }
494 new_mm->ldt.entry_count = 0;
495 }
496 else if (!ptrace_ldt) {
497 /* Our local LDT is used to supply the data for
498 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
499 * i.e., we have to use the stub for modify_ldt, which
500 * can't handle the big read buffer of up to 64kB.
501 */
502 down(&from_mm->ldt.semaphore);
503 if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){
504 memcpy(new_mm->ldt.entries, from_mm->ldt.entries,
505 sizeof(new_mm->ldt.entries));
506 }
507 else{
508 i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
509 while(i-->0){
510 page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
511 if (!page){
512 err = -ENOMEM;
513 break;
514 }
515 new_mm->ldt.pages[i] = (struct ldt_entry*)page;
516 memcpy(new_mm->ldt.pages[i],
517 from_mm->ldt.pages[i], PAGE_SIZE);
518 }
519 }
520 new_mm->ldt.entry_count = from_mm->ldt.entry_count;
521 up(&from_mm->ldt.semaphore);
522 }
523
524 return err;
525}
526
527
528void free_ldt(struct mmu_context_skas * mm)
529{
530 int i;
531
532 if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){
533 i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
534 while(i-- > 0){
535 free_page((long )mm->ldt.pages[i]);
536 }
537 }
538 mm->ldt.entry_count = 0;
539}
540#endif
541
542int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
543{
544 return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
545 ptr, bytecount));
546}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 06c3633457a2..ea977df395a1 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,7 +5,7 @@
5# 5#
6 6
7#XXX: why into lib-y? 7#XXX: why into lib-y?
8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ 8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \
9 ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \ 9 ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \
10 stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o 10 stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
11 11
@@ -14,7 +14,7 @@ obj-$(CONFIG_MODULES) += module.o um_module.o
14 14
15USER_OBJS := ptrace_user.o sigcontext.o 15USER_OBJS := ptrace_user.o sigcontext.o
16 16
17SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ 17SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \
18 thunk.S module.c 18 thunk.S module.c
19 19
20include arch/um/scripts/Makefile.rules 20include arch/um/scripts/Makefile.rules
@@ -23,6 +23,7 @@ bitops.c-dir = lib
23csum-copy.S-dir = lib 23csum-copy.S-dir = lib
24csum-partial.c-dir = lib 24csum-partial.c-dir = lib
25csum-wrappers.c-dir = lib 25csum-wrappers.c-dir = lib
26ldt.c-dir = /arch/um/sys-i386
26memcpy.S-dir = lib 27memcpy.S-dir = lib
27thunk.S-dir = lib 28thunk.S-dir = lib
28module.c-dir = kernel 29module.c-dir = kernel
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 3259a4db4534..6acee5c4ada6 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -29,81 +29,6 @@ asmlinkage long sys_uname64(struct new_utsname __user * name)
29} 29}
30 30
31#ifdef CONFIG_MODE_TT 31#ifdef CONFIG_MODE_TT
32extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
33
34long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
35{
36 /* XXX This should check VERIFY_WRITE depending on func, check this
37 * in i386 as well.
38 */
39 if (!access_ok(VERIFY_READ, ptr, bytecount))
40 return -EFAULT;
41 return(modify_ldt(func, ptr, bytecount));
42}
43#endif
44
45#ifdef CONFIG_MODE_SKAS
46extern int userspace_pid[];
47
48#include "skas_ptrace.h"
49
50long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
51{
52 struct ptrace_ldt ldt;
53 void *buf;
54 int res, n;
55
56 buf = kmalloc(bytecount, GFP_KERNEL);
57 if(buf == NULL)
58 return(-ENOMEM);
59
60 res = 0;
61
62 switch(func){
63 case 1:
64 case 0x11:
65 res = copy_from_user(buf, ptr, bytecount);
66 break;
67 }
68
69 if(res != 0){
70 res = -EFAULT;
71 goto out;
72 }
73
74 ldt = ((struct ptrace_ldt) { .func = func,
75 .ptr = buf,
76 .bytecount = bytecount });
77#warning Need to look up userspace_pid by cpu
78 res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
79 if(res < 0)
80 goto out;
81
82 switch(func){
83 case 0:
84 case 2:
85 n = res;
86 res = copy_to_user(ptr, buf, n);
87 if(res != 0)
88 res = -EFAULT;
89 else
90 res = n;
91 break;
92 }
93
94 out:
95 kfree(buf);
96 return(res);
97}
98#endif
99
100long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
101{
102 return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
103 ptr, bytecount));
104}
105
106#ifdef CONFIG_MODE_TT
107extern long arch_prctl(int code, unsigned long addr); 32extern long arch_prctl(int code, unsigned long addr);
108 33
109static long arch_prctl_tt(int code, unsigned long addr) 34static long arch_prctl_tt(int code, unsigned long addr)
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index d6077ff47d22..18492d02aaf6 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -113,45 +113,10 @@ static int set_single_step (struct task_struct *t, int val)
113 return 1; 113 return 1;
114} 114}
115 115
116long sys_ptrace(long request, long pid, long addr, long data) 116long arch_ptrace(struct task_struct *child, long request, long addr, long data)
117{ 117{
118 struct task_struct *child;
119 int rval; 118 int rval;
120 119
121 lock_kernel();
122
123 if (request == PTRACE_TRACEME) {
124 /* are we already being traced? */
125 if (current->ptrace & PT_PTRACED) {
126 rval = -EPERM;
127 goto out;
128 }
129 /* set the ptrace bit in the process flags. */
130 current->ptrace |= PT_PTRACED;
131 rval = 0;
132 goto out;
133 }
134 rval = -ESRCH;
135 read_lock(&tasklist_lock);
136 child = find_task_by_pid(pid);
137 if (child)
138 get_task_struct(child);
139 read_unlock(&tasklist_lock);
140 if (!child)
141 goto out;
142
143 rval = -EPERM;
144 if (pid == 1) /* you may not mess with init */
145 goto out_tsk;
146
147 if (request == PTRACE_ATTACH) {
148 rval = ptrace_attach(child);
149 goto out_tsk;
150 }
151 rval = ptrace_check_attach(child, request == PTRACE_KILL);
152 if (rval < 0)
153 goto out_tsk;
154
155 switch (request) { 120 switch (request) {
156 unsigned long val, copied; 121 unsigned long val, copied;
157 122
@@ -248,11 +213,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
248 rval = -EIO; 213 rval = -EIO;
249 goto out; 214 goto out;
250 } 215 }
251 216 out:
252out_tsk:
253 put_task_struct(child);
254out:
255 unlock_kernel();
256 return rval; 217 return rval;
257} 218}
258 219
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 21afa69a086d..4cce2f6f170c 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -532,8 +532,21 @@ source "drivers/firmware/Kconfig"
532 532
533source fs/Kconfig 533source fs/Kconfig
534 534
535menu "Instrumentation Support"
536 depends on EXPERIMENTAL
537
535source "arch/x86_64/oprofile/Kconfig" 538source "arch/x86_64/oprofile/Kconfig"
536 539
540config KPROBES
541 bool "Kprobes (EXPERIMENTAL)"
542 help
543 Kprobes allows you to trap at almost any kernel address and
544 execute a callback function. register_kprobe() establishes
545 a probepoint and specifies the callback. Kprobes is useful
546 for kernel debugging, non-intrusive instrumentation and testing.
547 If in doubt, say "N".
548endmenu
549
537source "arch/x86_64/Kconfig.debug" 550source "arch/x86_64/Kconfig.debug"
538 551
539source "security/Kconfig" 552source "security/Kconfig"
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index 9cf1410d2f5a..d584ecc27ea1 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -33,16 +33,6 @@ config IOMMU_DEBUG
33 options. See Documentation/x86_64/boot-options.txt for more 33 options. See Documentation/x86_64/boot-options.txt for more
34 details. 34 details.
35 35
36config KPROBES
37 bool "Kprobes"
38 depends on DEBUG_KERNEL
39 help
40 Kprobes allows you to trap at almost any kernel address and
41 execute a callback function. register_kprobe() establishes
42 a probepoint and specifies the callback. Kprobes is useful
43 for kernel debugging, non-intrusive instrumentation and testing.
44 If in doubt, say "N".
45
46config IOMMU_LEAK 36config IOMMU_LEAK
47 bool "IOMMU leak tracing" 37 bool "IOMMU leak tracing"
48 depends on DEBUG_KERNEL 38 depends on DEBUG_KERNEL
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 76a28b007be9..dddeb678b440 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -34,7 +34,6 @@
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/kprobes.h> 35#include <linux/kprobes.h>
36#include <linux/ptrace.h> 36#include <linux/ptrace.h>
37#include <linux/spinlock.h>
38#include <linux/string.h> 37#include <linux/string.h>
39#include <linux/slab.h> 38#include <linux/slab.h>
40#include <linux/preempt.h> 39#include <linux/preempt.h>
@@ -44,17 +43,10 @@
44#include <asm/kdebug.h> 43#include <asm/kdebug.h>
45 44
46static DECLARE_MUTEX(kprobe_mutex); 45static DECLARE_MUTEX(kprobe_mutex);
47
48static struct kprobe *current_kprobe;
49static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
50static struct kprobe *kprobe_prev;
51static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
52static struct pt_regs jprobe_saved_regs;
53static long *jprobe_saved_rsp;
54void jprobe_return_end(void); 46void jprobe_return_end(void);
55 47
56/* copy of the kernel stack at the probe fire time */ 48DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
57static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; 49DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
58 50
59/* 51/*
60 * returns non-zero if opcode modifies the interrupt flag. 52 * returns non-zero if opcode modifies the interrupt flag.
@@ -236,29 +228,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
236 up(&kprobe_mutex); 228 up(&kprobe_mutex);
237} 229}
238 230
239static inline void save_previous_kprobe(void) 231static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
240{ 232{
241 kprobe_prev = current_kprobe; 233 kcb->prev_kprobe.kp = kprobe_running();
242 kprobe_status_prev = kprobe_status; 234 kcb->prev_kprobe.status = kcb->kprobe_status;
243 kprobe_old_rflags_prev = kprobe_old_rflags; 235 kcb->prev_kprobe.old_rflags = kcb->kprobe_old_rflags;
244 kprobe_saved_rflags_prev = kprobe_saved_rflags; 236 kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
245} 237}
246 238
247static inline void restore_previous_kprobe(void) 239static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
248{ 240{
249 current_kprobe = kprobe_prev; 241 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
250 kprobe_status = kprobe_status_prev; 242 kcb->kprobe_status = kcb->prev_kprobe.status;
251 kprobe_old_rflags = kprobe_old_rflags_prev; 243 kcb->kprobe_old_rflags = kcb->prev_kprobe.old_rflags;
252 kprobe_saved_rflags = kprobe_saved_rflags_prev; 244 kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
253} 245}
254 246
255static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs) 247static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
248 struct kprobe_ctlblk *kcb)
256{ 249{
257 current_kprobe = p; 250 __get_cpu_var(current_kprobe) = p;
258 kprobe_saved_rflags = kprobe_old_rflags 251 kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags
259 = (regs->eflags & (TF_MASK | IF_MASK)); 252 = (regs->eflags & (TF_MASK | IF_MASK));
260 if (is_IF_modifier(p->ainsn.insn)) 253 if (is_IF_modifier(p->ainsn.insn))
261 kprobe_saved_rflags &= ~IF_MASK; 254 kcb->kprobe_saved_rflags &= ~IF_MASK;
262} 255}
263 256
264static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 257static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -272,6 +265,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
272 regs->rip = (unsigned long)p->ainsn.insn; 265 regs->rip = (unsigned long)p->ainsn.insn;
273} 266}
274 267
268/* Called with kretprobe_lock held */
275void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, 269void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
276 struct pt_regs *regs) 270 struct pt_regs *regs)
277{ 271{
@@ -292,32 +286,30 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
292 } 286 }
293} 287}
294 288
295/*
296 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
297 * remain disabled thorough out this function.
298 */
299int __kprobes kprobe_handler(struct pt_regs *regs) 289int __kprobes kprobe_handler(struct pt_regs *regs)
300{ 290{
301 struct kprobe *p; 291 struct kprobe *p;
302 int ret = 0; 292 int ret = 0;
303 kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t)); 293 kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
294 struct kprobe_ctlblk *kcb;
304 295
305 /* We're in an interrupt, but this is clear and BUG()-safe. */ 296 /*
297 * We don't want to be preempted for the entire
298 * duration of kprobe processing
299 */
306 preempt_disable(); 300 preempt_disable();
301 kcb = get_kprobe_ctlblk();
307 302
308 /* Check we're not actually recursing */ 303 /* Check we're not actually recursing */
309 if (kprobe_running()) { 304 if (kprobe_running()) {
310 /* We *are* holding lock here, so this is safe.
311 Disarm the probe we just hit, and ignore it. */
312 p = get_kprobe(addr); 305 p = get_kprobe(addr);
313 if (p) { 306 if (p) {
314 if (kprobe_status == KPROBE_HIT_SS && 307 if (kcb->kprobe_status == KPROBE_HIT_SS &&
315 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { 308 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
316 regs->eflags &= ~TF_MASK; 309 regs->eflags &= ~TF_MASK;
317 regs->eflags |= kprobe_saved_rflags; 310 regs->eflags |= kcb->kprobe_saved_rflags;
318 unlock_kprobes();
319 goto no_kprobe; 311 goto no_kprobe;
320 } else if (kprobe_status == KPROBE_HIT_SSDONE) { 312 } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) {
321 /* TODO: Provide re-entrancy from 313 /* TODO: Provide re-entrancy from
322 * post_kprobes_handler() and avoid exception 314 * post_kprobes_handler() and avoid exception
323 * stack corruption while single-stepping on 315 * stack corruption while single-stepping on
@@ -325,6 +317,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
325 */ 317 */
326 arch_disarm_kprobe(p); 318 arch_disarm_kprobe(p);
327 regs->rip = (unsigned long)p->addr; 319 regs->rip = (unsigned long)p->addr;
320 reset_current_kprobe();
328 ret = 1; 321 ret = 1;
329 } else { 322 } else {
330 /* We have reentered the kprobe_handler(), since 323 /* We have reentered the kprobe_handler(), since
@@ -334,27 +327,24 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
334 * of the new probe without calling any user 327 * of the new probe without calling any user
335 * handlers. 328 * handlers.
336 */ 329 */
337 save_previous_kprobe(); 330 save_previous_kprobe(kcb);
338 set_current_kprobe(p, regs); 331 set_current_kprobe(p, regs, kcb);
339 p->nmissed++; 332 p->nmissed++;
340 prepare_singlestep(p, regs); 333 prepare_singlestep(p, regs);
341 kprobe_status = KPROBE_REENTER; 334 kcb->kprobe_status = KPROBE_REENTER;
342 return 1; 335 return 1;
343 } 336 }
344 } else { 337 } else {
345 p = current_kprobe; 338 p = __get_cpu_var(current_kprobe);
346 if (p->break_handler && p->break_handler(p, regs)) { 339 if (p->break_handler && p->break_handler(p, regs)) {
347 goto ss_probe; 340 goto ss_probe;
348 } 341 }
349 } 342 }
350 /* If it's not ours, can't be delete race, (we hold lock). */
351 goto no_kprobe; 343 goto no_kprobe;
352 } 344 }
353 345
354 lock_kprobes();
355 p = get_kprobe(addr); 346 p = get_kprobe(addr);
356 if (!p) { 347 if (!p) {
357 unlock_kprobes();
358 if (*addr != BREAKPOINT_INSTRUCTION) { 348 if (*addr != BREAKPOINT_INSTRUCTION) {
359 /* 349 /*
360 * The breakpoint instruction was removed right 350 * The breakpoint instruction was removed right
@@ -372,8 +362,8 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
372 goto no_kprobe; 362 goto no_kprobe;
373 } 363 }
374 364
375 kprobe_status = KPROBE_HIT_ACTIVE; 365 set_current_kprobe(p, regs, kcb);
376 set_current_kprobe(p, regs); 366 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
377 367
378 if (p->pre_handler && p->pre_handler(p, regs)) 368 if (p->pre_handler && p->pre_handler(p, regs))
379 /* handler has already set things up, so skip ss setup */ 369 /* handler has already set things up, so skip ss setup */
@@ -381,7 +371,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
381 371
382ss_probe: 372ss_probe:
383 prepare_singlestep(p, regs); 373 prepare_singlestep(p, regs);
384 kprobe_status = KPROBE_HIT_SS; 374 kcb->kprobe_status = KPROBE_HIT_SS;
385 return 1; 375 return 1;
386 376
387no_kprobe: 377no_kprobe:
@@ -409,9 +399,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
409 struct kretprobe_instance *ri = NULL; 399 struct kretprobe_instance *ri = NULL;
410 struct hlist_head *head; 400 struct hlist_head *head;
411 struct hlist_node *node, *tmp; 401 struct hlist_node *node, *tmp;
412 unsigned long orig_ret_address = 0; 402 unsigned long flags, orig_ret_address = 0;
413 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; 403 unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
414 404
405 spin_lock_irqsave(&kretprobe_lock, flags);
415 head = kretprobe_inst_table_head(current); 406 head = kretprobe_inst_table_head(current);
416 407
417 /* 408 /*
@@ -450,13 +441,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
450 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); 441 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
451 regs->rip = orig_ret_address; 442 regs->rip = orig_ret_address;
452 443
453 unlock_kprobes(); 444 reset_current_kprobe();
445 spin_unlock_irqrestore(&kretprobe_lock, flags);
454 preempt_enable_no_resched(); 446 preempt_enable_no_resched();
455 447
456 /* 448 /*
457 * By returning a non-zero value, we are telling 449 * By returning a non-zero value, we are telling
458 * kprobe_handler() that we have handled unlocking 450 * kprobe_handler() that we don't want the post_handler
459 * and re-enabling preemption. 451 * to run (and have re-enabled preemption)
460 */ 452 */
461 return 1; 453 return 1;
462} 454}
@@ -483,7 +475,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
483 * that is atop the stack is the address following the copied instruction. 475 * that is atop the stack is the address following the copied instruction.
484 * We need to make it the address following the original instruction. 476 * We need to make it the address following the original instruction.
485 */ 477 */
486static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) 478static void __kprobes resume_execution(struct kprobe *p,
479 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
487{ 480{
488 unsigned long *tos = (unsigned long *)regs->rsp; 481 unsigned long *tos = (unsigned long *)regs->rsp;
489 unsigned long next_rip = 0; 482 unsigned long next_rip = 0;
@@ -498,7 +491,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
498 switch (*insn) { 491 switch (*insn) {
499 case 0x9c: /* pushfl */ 492 case 0x9c: /* pushfl */
500 *tos &= ~(TF_MASK | IF_MASK); 493 *tos &= ~(TF_MASK | IF_MASK);
501 *tos |= kprobe_old_rflags; 494 *tos |= kcb->kprobe_old_rflags;
502 break; 495 break;
503 case 0xc3: /* ret/lret */ 496 case 0xc3: /* ret/lret */
504 case 0xcb: 497 case 0xcb:
@@ -537,30 +530,28 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
537 } 530 }
538} 531}
539 532
540/*
541 * Interrupts are disabled on entry as trap1 is an interrupt gate and they
542 * remain disabled thoroughout this function. And we hold kprobe lock.
543 */
544int __kprobes post_kprobe_handler(struct pt_regs *regs) 533int __kprobes post_kprobe_handler(struct pt_regs *regs)
545{ 534{
546 if (!kprobe_running()) 535 struct kprobe *cur = kprobe_running();
536 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
537
538 if (!cur)
547 return 0; 539 return 0;
548 540
549 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { 541 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
550 kprobe_status = KPROBE_HIT_SSDONE; 542 kcb->kprobe_status = KPROBE_HIT_SSDONE;
551 current_kprobe->post_handler(current_kprobe, regs, 0); 543 cur->post_handler(cur, regs, 0);
552 } 544 }
553 545
554 resume_execution(current_kprobe, regs); 546 resume_execution(cur, regs, kcb);
555 regs->eflags |= kprobe_saved_rflags; 547 regs->eflags |= kcb->kprobe_saved_rflags;
556 548
557 /* Restore the original saved kprobes variables and continue. */ 549 /* Restore the original saved kprobes variables and continue. */
558 if (kprobe_status == KPROBE_REENTER) { 550 if (kcb->kprobe_status == KPROBE_REENTER) {
559 restore_previous_kprobe(); 551 restore_previous_kprobe(kcb);
560 goto out; 552 goto out;
561 } else {
562 unlock_kprobes();
563 } 553 }
554 reset_current_kprobe();
564out: 555out:
565 preempt_enable_no_resched(); 556 preempt_enable_no_resched();
566 557
@@ -575,18 +566,19 @@ out:
575 return 1; 566 return 1;
576} 567}
577 568
578/* Interrupts disabled, kprobe_lock held. */
579int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 569int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
580{ 570{
581 if (current_kprobe->fault_handler 571 struct kprobe *cur = kprobe_running();
582 && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) 572 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
573
574 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
583 return 1; 575 return 1;
584 576
585 if (kprobe_status & KPROBE_HIT_SS) { 577 if (kcb->kprobe_status & KPROBE_HIT_SS) {
586 resume_execution(current_kprobe, regs); 578 resume_execution(cur, regs, kcb);
587 regs->eflags |= kprobe_old_rflags; 579 regs->eflags |= kcb->kprobe_old_rflags;
588 580
589 unlock_kprobes(); 581 reset_current_kprobe();
590 preempt_enable_no_resched(); 582 preempt_enable_no_resched();
591 } 583 }
592 return 0; 584 return 0;
@@ -599,39 +591,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
599 unsigned long val, void *data) 591 unsigned long val, void *data)
600{ 592{
601 struct die_args *args = (struct die_args *)data; 593 struct die_args *args = (struct die_args *)data;
594 int ret = NOTIFY_DONE;
595
602 switch (val) { 596 switch (val) {
603 case DIE_INT3: 597 case DIE_INT3:
604 if (kprobe_handler(args->regs)) 598 if (kprobe_handler(args->regs))
605 return NOTIFY_STOP; 599 ret = NOTIFY_STOP;
606 break; 600 break;
607 case DIE_DEBUG: 601 case DIE_DEBUG:
608 if (post_kprobe_handler(args->regs)) 602 if (post_kprobe_handler(args->regs))
609 return NOTIFY_STOP; 603 ret = NOTIFY_STOP;
610 break; 604 break;
611 case DIE_GPF: 605 case DIE_GPF:
612 if (kprobe_running() &&
613 kprobe_fault_handler(args->regs, args->trapnr))
614 return NOTIFY_STOP;
615 break;
616 case DIE_PAGE_FAULT: 606 case DIE_PAGE_FAULT:
607 /* kprobe_running() needs smp_processor_id() */
608 preempt_disable();
617 if (kprobe_running() && 609 if (kprobe_running() &&
618 kprobe_fault_handler(args->regs, args->trapnr)) 610 kprobe_fault_handler(args->regs, args->trapnr))
619 return NOTIFY_STOP; 611 ret = NOTIFY_STOP;
612 preempt_enable();
620 break; 613 break;
621 default: 614 default:
622 break; 615 break;
623 } 616 }
624 return NOTIFY_DONE; 617 return ret;
625} 618}
626 619
627int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 620int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
628{ 621{
629 struct jprobe *jp = container_of(p, struct jprobe, kp); 622 struct jprobe *jp = container_of(p, struct jprobe, kp);
630 unsigned long addr; 623 unsigned long addr;
624 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
631 625
632 jprobe_saved_regs = *regs; 626 kcb->jprobe_saved_regs = *regs;
633 jprobe_saved_rsp = (long *) regs->rsp; 627 kcb->jprobe_saved_rsp = (long *) regs->rsp;
634 addr = (unsigned long)jprobe_saved_rsp; 628 addr = (unsigned long)(kcb->jprobe_saved_rsp);
635 /* 629 /*
636 * As Linus pointed out, gcc assumes that the callee 630 * As Linus pointed out, gcc assumes that the callee
637 * owns the argument space and could overwrite it, e.g. 631 * owns the argument space and could overwrite it, e.g.
@@ -639,7 +633,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
639 * we also save and restore enough stack bytes to cover 633 * we also save and restore enough stack bytes to cover
640 * the argument area. 634 * the argument area.
641 */ 635 */
642 memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr)); 636 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
637 MIN_STACK_SIZE(addr));
643 regs->eflags &= ~IF_MASK; 638 regs->eflags &= ~IF_MASK;
644 regs->rip = (unsigned long)(jp->entry); 639 regs->rip = (unsigned long)(jp->entry);
645 return 1; 640 return 1;
@@ -647,36 +642,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
647 642
648void __kprobes jprobe_return(void) 643void __kprobes jprobe_return(void)
649{ 644{
650 preempt_enable_no_resched(); 645 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
646
651 asm volatile (" xchg %%rbx,%%rsp \n" 647 asm volatile (" xchg %%rbx,%%rsp \n"
652 " int3 \n" 648 " int3 \n"
653 " .globl jprobe_return_end \n" 649 " .globl jprobe_return_end \n"
654 " jprobe_return_end: \n" 650 " jprobe_return_end: \n"
655 " nop \n"::"b" 651 " nop \n"::"b"
656 (jprobe_saved_rsp):"memory"); 652 (kcb->jprobe_saved_rsp):"memory");
657} 653}
658 654
659int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 655int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
660{ 656{
657 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
661 u8 *addr = (u8 *) (regs->rip - 1); 658 u8 *addr = (u8 *) (regs->rip - 1);
662 unsigned long stack_addr = (unsigned long)jprobe_saved_rsp; 659 unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp);
663 struct jprobe *jp = container_of(p, struct jprobe, kp); 660 struct jprobe *jp = container_of(p, struct jprobe, kp);
664 661
665 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { 662 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
666 if ((long *)regs->rsp != jprobe_saved_rsp) { 663 if ((long *)regs->rsp != kcb->jprobe_saved_rsp) {
667 struct pt_regs *saved_regs = 664 struct pt_regs *saved_regs =
668 container_of(jprobe_saved_rsp, struct pt_regs, rsp); 665 container_of(kcb->jprobe_saved_rsp,
666 struct pt_regs, rsp);
669 printk("current rsp %p does not match saved rsp %p\n", 667 printk("current rsp %p does not match saved rsp %p\n",
670 (long *)regs->rsp, jprobe_saved_rsp); 668 (long *)regs->rsp, kcb->jprobe_saved_rsp);
671 printk("Saved registers for jprobe %p\n", jp); 669 printk("Saved registers for jprobe %p\n", jp);
672 show_registers(saved_regs); 670 show_registers(saved_regs);
673 printk("Current registers\n"); 671 printk("Current registers\n");
674 show_registers(regs); 672 show_registers(regs);
675 BUG(); 673 BUG();
676 } 674 }
677 *regs = jprobe_saved_regs; 675 *regs = kcb->jprobe_saved_regs;
678 memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack, 676 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
679 MIN_STACK_SIZE(stack_addr)); 677 MIN_STACK_SIZE(stack_addr));
678 preempt_enable_no_resched();
680 return 1; 679 return 1;
681 } 680 }
682 return 0; 681 return 0;
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index bbf64b59a21e..a87b6cebe80f 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -313,48 +313,11 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
313 313
314} 314}
315 315
316asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data) 316long arch_ptrace(struct task_struct *child, long request, long addr, long data)
317{ 317{
318 struct task_struct *child;
319 long i, ret; 318 long i, ret;
320 unsigned ui; 319 unsigned ui;
321 320
322 /* This lock_kernel fixes a subtle race with suid exec */
323 lock_kernel();
324 ret = -EPERM;
325 if (request == PTRACE_TRACEME) {
326 /* are we already being traced? */
327 if (current->ptrace & PT_PTRACED)
328 goto out;
329 ret = security_ptrace(current->parent, current);
330 if (ret)
331 goto out;
332 /* set the ptrace bit in the process flags. */
333 current->ptrace |= PT_PTRACED;
334 ret = 0;
335 goto out;
336 }
337 ret = -ESRCH;
338 read_lock(&tasklist_lock);
339 child = find_task_by_pid(pid);
340 if (child)
341 get_task_struct(child);
342 read_unlock(&tasklist_lock);
343 if (!child)
344 goto out;
345
346 ret = -EPERM;
347 if (pid == 1) /* you may not mess with init */
348 goto out_tsk;
349
350 if (request == PTRACE_ATTACH) {
351 ret = ptrace_attach(child);
352 goto out_tsk;
353 }
354 ret = ptrace_check_attach(child, request == PTRACE_KILL);
355 if (ret < 0)
356 goto out_tsk;
357
358 switch (request) { 321 switch (request) {
359 /* when I and D space are separate, these will need to be fixed. */ 322 /* when I and D space are separate, these will need to be fixed. */
360 case PTRACE_PEEKTEXT: /* read word at location addr. */ 323 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -608,10 +571,6 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
608 ret = ptrace_request(child, request, addr, data); 571 ret = ptrace_request(child, request, addr, data);
609 break; 572 break;
610 } 573 }
611out_tsk:
612 put_task_struct(child);
613out:
614 unlock_kernel();
615 return ret; 574 return ret;
616} 575}
617 576
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 658a81b33f3b..4b5b088ec102 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -65,8 +65,6 @@ int smp_num_siblings = 1;
65/* Package ID of each logical CPU */ 65/* Package ID of each logical CPU */
66u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; 66u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
67u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; 67u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
68EXPORT_SYMBOL(phys_proc_id);
69EXPORT_SYMBOL(cpu_core_id);
70 68
71/* Bitmask of currently online CPUs */ 69/* Bitmask of currently online CPUs */
72cpumask_t cpu_online_map __read_mostly; 70cpumask_t cpu_online_map __read_mostly;
diff --git a/arch/x86_64/oprofile/Kconfig b/arch/x86_64/oprofile/Kconfig
index 5ade19801b97..d8a84088471a 100644
--- a/arch/x86_64/oprofile/Kconfig
+++ b/arch/x86_64/oprofile/Kconfig
@@ -1,7 +1,3 @@
1
2menu "Profiling support"
3 depends on EXPERIMENTAL
4
5config PROFILING 1config PROFILING
6 bool "Profiling support (EXPERIMENTAL)" 2 bool "Profiling support (EXPERIMENTAL)"
7 help 3 help
@@ -19,5 +15,3 @@ config OPROFILE
19 15
20 If unsure, say N. 16 If unsure, say N.
21 17
22endmenu
23
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 14460743de07..ab5c4c65b5c4 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -45,58 +45,10 @@ void ptrace_disable(struct task_struct *child)
45 /* Nothing to do.. */ 45 /* Nothing to do.. */
46} 46}
47 47
48long sys_ptrace(long request, long pid, long addr, long data) 48long arch_ptrace(struct task_struct *child, long request, long addr, long data)
49{ 49{
50 struct task_struct *child;
51 int ret = -EPERM; 50 int ret = -EPERM;
52 51
53 lock_kernel();
54
55#if 0
56 if ((int)request != 1)
57 printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
58 (int) request, (int) pid, (unsigned long) addr,
59 (unsigned long) data);
60#endif
61
62 if (request == PTRACE_TRACEME) {
63
64 /* Are we already being traced? */
65
66 if (current->ptrace & PT_PTRACED)
67 goto out;
68
69 if ((ret = security_ptrace(current->parent, current)))
70 goto out;
71
72 /* Set the ptrace bit in the process flags. */
73
74 current->ptrace |= PT_PTRACED;
75 ret = 0;
76 goto out;
77 }
78
79 ret = -ESRCH;
80 read_lock(&tasklist_lock);
81 child = find_task_by_pid(pid);
82 if (child)
83 get_task_struct(child);
84 read_unlock(&tasklist_lock);
85 if (!child)
86 goto out;
87
88 ret = -EPERM;
89 if (pid == 1) /* you may not mess with init */
90 goto out;
91
92 if (request == PTRACE_ATTACH) {
93 ret = ptrace_attach(child);
94 goto out_tsk;
95 }
96
97 if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
98 goto out_tsk;
99
100 switch (request) { 52 switch (request) {
101 case PTRACE_PEEKTEXT: /* read word at location addr. */ 53 case PTRACE_PEEKTEXT: /* read word at location addr. */
102 case PTRACE_PEEKDATA: 54 case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
375 ret = ptrace_request(child, request, addr, data); 327 ret = ptrace_request(child, request, addr, data);
376 goto out; 328 goto out;
377 } 329 }
378out_tsk: 330 out:
379 put_task_struct(child);
380out:
381 unlock_kernel();
382 return ret; 331 return ret;
383} 332}
384 333