summaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/Kconfig3
-rw-r--r--arch/microblaze/Makefile2
-rw-r--r--arch/microblaze/boot/Makefile19
-rw-r--r--arch/microblaze/boot/dts/Makefile22
-rw-r--r--arch/microblaze/boot/dts/linked_dtb.S2
-rw-r--r--arch/microblaze/boot/linked_dtb.S3
-rw-r--r--arch/microblaze/include/asm/Kbuild2
-rw-r--r--arch/microblaze/include/asm/processor.h8
-rw-r--r--arch/microblaze/include/asm/syscalls.h16
-rw-r--r--arch/microblaze/include/asm/unistd.h6
-rw-r--r--arch/microblaze/kernel/entry-nommu.S20
-rw-r--r--arch/microblaze/kernel/entry.S57
-rw-r--r--arch/microblaze/kernel/process.c75
-rw-r--r--arch/microblaze/kernel/signal.c2
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c53
-rw-r--r--arch/microblaze/kernel/syscall_table.S6
-rw-r--r--arch/microblaze/pci/pci-common.c4
17 files changed, 80 insertions, 220 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 4cba7439f9de..4bcf89148f3c 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -26,6 +26,9 @@ config MICROBLAZE
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
+ select CLONE_BACKWARDS
config SWAP
def_bool n
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index b23c40eb7a52..d26fb905ee0a 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -57,7 +57,7 @@ boot := arch/microblaze/boot
DTB:=$(subst simpleImage.,,$(filter simpleImage.%, $(MAKECMDGOALS)))
ifneq ($(DTB),)
- core-y += $(boot)/
+ core-y += $(boot)/dts/
endif
# defines filename extension depending memory management type
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index fa83ea497db7..80fe54fb7ca3 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -2,21 +2,10 @@
# arch/microblaze/boot/Makefile
#
-obj-y += linked_dtb.o
-
targets := linux.bin linux.bin.gz simpleImage.%
OBJCOPYFLAGS := -R .note -R .comment -R .note.gnu.build-id -O binary
-# Ensure system.dtb exists
-$(obj)/linked_dtb.o: $(obj)/system.dtb
-
-# Generate system.dtb from $(DTB).dtb
-ifneq ($(DTB),system)
-$(obj)/system.dtb: $(obj)/$(DTB).dtb
- $(call if_changed,cp)
-endif
-
$(obj)/linux.bin: vmlinux FORCE
$(call if_changed,objcopy)
$(call if_changed,uimage)
@@ -45,10 +34,4 @@ $(obj)/simpleImage.%: vmlinux FORCE
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
-# Rule to build device tree blobs
-DTC_FLAGS := -p 1024
-
-$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call if_changed_dep,dtc)
-
-clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
+clean-files += simpleImage.*.unstrip linux.bin.ub
diff --git a/arch/microblaze/boot/dts/Makefile b/arch/microblaze/boot/dts/Makefile
new file mode 100644
index 000000000000..c3b3a5d67b89
--- /dev/null
+++ b/arch/microblaze/boot/dts/Makefile
@@ -0,0 +1,22 @@
+#
+# arch/microblaze/boot/Makefile
+#
+
+obj-y += linked_dtb.o
+
+# Ensure system.dtb exists
+$(obj)/linked_dtb.o: $(obj)/system.dtb
+
+# Generate system.dtb from $(DTB).dtb
+ifneq ($(DTB),system)
+$(obj)/system.dtb: $(obj)/$(DTB).dtb
+ $(call if_changed,cp)
+endif
+
+quiet_cmd_cp = CP $< $@$2
+ cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
+
+# Rule to build device tree blobs
+DTC_FLAGS := -p 1024
+
+clean-files += *.dtb
diff --git a/arch/microblaze/boot/dts/linked_dtb.S b/arch/microblaze/boot/dts/linked_dtb.S
new file mode 100644
index 000000000000..23345af3721f
--- /dev/null
+++ b/arch/microblaze/boot/dts/linked_dtb.S
@@ -0,0 +1,2 @@
+.section __fdt_blob,"a"
+.incbin "arch/microblaze/boot/dts/system.dtb"
diff --git a/arch/microblaze/boot/linked_dtb.S b/arch/microblaze/boot/linked_dtb.S
deleted file mode 100644
index cb2b537aebee..000000000000
--- a/arch/microblaze/boot/linked_dtb.S
+++ /dev/null
@@ -1,3 +0,0 @@
-.section __fdt_blob,"a"
-.incbin "arch/microblaze/boot/system.dtb"
-
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index 8653072d7e9f..eb3a46c096fe 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -3,3 +3,5 @@ include include/asm-generic/Kbuild.asm
header-y += elf.h
generic-y += clkdev.h
generic-y += exec.h
+generic-y += trace_clock.h
+generic-y += syscalls.h
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h
index af2bb9652392..0759153e8117 100644
--- a/arch/microblaze/include/asm/processor.h
+++ b/arch/microblaze/include/asm/processor.h
@@ -31,6 +31,7 @@ extern const struct seq_operations cpuinfo_op;
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp);
extern void ret_from_fork(void);
+extern void ret_from_kernel_thread(void);
# endif /* __ASSEMBLY__ */
@@ -78,11 +79,6 @@ extern unsigned long thread_saved_pc(struct task_struct *t);
extern unsigned long get_wchan(struct task_struct *p);
-/*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
# define KSTK_EIP(tsk) (0)
# define KSTK_ESP(tsk) (0)
@@ -131,8 +127,6 @@ extern inline void release_thread(struct task_struct *dead_task)
{
}
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
/* Free current thread data structures etc. */
static inline void exit_thread(void)
{
diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h
deleted file mode 100644
index 27f2f4c0f39f..000000000000
--- a/arch/microblaze/include/asm/syscalls.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_MICROBLAZE_SYSCALLS_H
-
-asmlinkage long microblaze_vfork(struct pt_regs *regs);
-asmlinkage long microblaze_clone(int flags, unsigned long stack,
- struct pt_regs *regs);
-asmlinkage long microblaze_execve(const char __user *filenamei,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs);
-
-asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
-#define sys_clone sys_clone
-
-#include <asm-generic/syscalls.h>
-
-#endif /* __ASM_MICROBLAZE_SYSCALLS_H */
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index 6985e6e9d826..94d978986b75 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -422,6 +422,12 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_VFORK
+#ifdef CONFIG_MMU
+#define __ARCH_WANT_SYS_FORK
+#endif
/*
* "Conditional" syscalls
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 75c3ea1f48a1..cb0327f204ab 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -474,6 +474,14 @@ ENTRY(ret_from_fork)
brid ret_to_user
nop
+ENTRY(ret_from_kernel_thread)
+ brlid r15, schedule_tail
+ addk r5, r0, r3
+ brald r15, r20
+ addk r5, r0, r19
+ brid ret_to_user
+ addk r3, r0, r0
+
work_pending:
enable_irq
@@ -551,18 +559,6 @@ no_work_pending:
rtid r14, 0
nop
-sys_vfork:
- brid microblaze_vfork
- addk r5, r1, r0
-
-sys_clone:
- brid microblaze_clone
- addk r7, r1, r0
-
-sys_execve:
- brid microblaze_execve
- addk r8, r1, r0
-
sys_rt_sigreturn_wrapper:
brid sys_rt_sigreturn
addk r5, r1, r0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 03f7b8ce6b6b..c217367dfc7b 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -293,24 +293,6 @@ C_ENTRY(_user_exception):
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
addi r14, r14, 4 /* return address is 4 byte after call */
- mfs r1, rmsr
- nop
- andi r1, r1, MSR_UMS
- bnei r1, 1f
-
-/* Kernel-mode state save - kernel execve */
- lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
- tophys(r1,r1);
-
- addik r1, r1, -PT_SIZE; /* Make room on the stack. */
- SAVE_REGS
-
- swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
- brid 2f;
- nop; /* Fill delay slot */
-
-/* User-mode state save. */
-1:
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
tophys(r1,r1);
lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
@@ -460,18 +442,6 @@ TRAP_return: /* Make global symbol for debugging */
nop;
-/* These syscalls need access to the struct pt_regs on the stack, so we
- implement them in assembly (they're basically all wrappers anyway). */
-
-C_ENTRY(sys_fork_wrapper):
- addi r5, r0, SIGCHLD /* Arg 0: flags */
- lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
- addik r7, r1, 0 /* Arg 2: parent context */
- add r8, r0, r0 /* Arg 3: (unused) */
- add r9, r0, r0; /* Arg 4: (unused) */
- brid do_fork /* Do real work (tail-call) */
- add r10, r0, r0; /* Arg 5: (unused) */
-
/* This the initial entry point for a new child thread, with an appropriate
stack in place that makes it look the the child is in the middle of an
syscall. This function is actually `returned to' from switch_thread
@@ -479,28 +449,19 @@ C_ENTRY(sys_fork_wrapper):
saved context). */
C_ENTRY(ret_from_fork):
bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
- add r3, r5, r0; /* switch_thread returns the prev task */
+ add r5, r3, r0; /* switch_thread returns the prev task */
/* ( in the delay slot ) */
brid ret_from_trap; /* Do normal trap return */
add r3, r0, r0; /* Child's fork call should return 0. */
-C_ENTRY(sys_vfork):
- brid microblaze_vfork /* Do real work (tail-call) */
- addik r5, r1, 0
-
-C_ENTRY(sys_clone):
- bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
- lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
-1: addik r7, r1, 0; /* Arg 2: parent context */
- lwi r9, r1, PT_R8; /* parent tid. */
- lwi r10, r1, PT_R9; /* child tid. */
- /* do_fork will pick up TLS from regs->r10. */
- brid do_fork /* Do real work (tail-call) */
- add r8, r0, r0; /* Arg 3: (unused) */
-
-C_ENTRY(sys_execve):
- brid microblaze_execve; /* Do real work (tail-call).*/
- addik r8, r1, 0; /* add user context as 4th arg */
+C_ENTRY(ret_from_kernel_thread):
+ bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
+ add r5, r3, r0; /* switch_thread returns the prev task */
+ /* ( in the delay slot ) */
+ brald r15, r20 /* fn was left in r20 */
+ addk r5, r0, r19 /* ... and argument - in r19 */
+ brid ret_from_trap
+ add r3, r0, r0
C_ENTRY(sys_rt_sigreturn_wrapper):
brid sys_rt_sigreturn /* Do real work */
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 1944e00f07e1..40823fd1db0b 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -13,6 +13,7 @@
#include <linux/pm.h>
#include <linux/tick.h>
#include <linux/bitops.h>
+#include <linux/ptrace.h>
#include <asm/pgalloc.h>
#include <asm/uaccess.h> /* for USER_DS macros */
#include <asm/cacheflush.h>
@@ -119,46 +120,38 @@ void flush_thread(void)
}
int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
- struct task_struct *p, struct pt_regs *regs)
+ unsigned long arg, struct task_struct *p)
{
struct pt_regs *childregs = task_pt_regs(p);
struct thread_info *ti = task_thread_info(p);
- *childregs = *regs;
- if (user_mode(regs))
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ /* if we're creating a new kernel thread then just zeroing all
+ * the registers. That's OK for a brand new thread.*/
+ memset(childregs, 0, sizeof(struct pt_regs));
+ memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
+ ti->cpu_context.r1 = (unsigned long)childregs;
+ ti->cpu_context.r20 = (unsigned long)usp; /* fn */
+ ti->cpu_context.r19 = (unsigned long)arg;
+ childregs->pt_mode = 1;
+ local_save_flags(childregs->msr);
+#ifdef CONFIG_MMU
+ ti->cpu_context.msr = childregs->msr & ~MSR_IE;
+#endif
+ ti->cpu_context.r15 = (unsigned long)ret_from_kernel_thread - 8;
+ return 0;
+ }
+ *childregs = *current_pt_regs();
+ if (usp)
childregs->r1 = usp;
- else
- childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
-#ifndef CONFIG_MMU
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
ti->cpu_context.r1 = (unsigned long)childregs;
+#ifndef CONFIG_MMU
ti->cpu_context.msr = (unsigned long)childregs->msr;
#else
+ childregs->msr |= MSR_UMS;
- /* if creating a kernel thread then update the current reg (we don't
- * want to use the parent's value when restoring by POP_STATE) */
- if (kernel_mode(regs))
- /* save new current on stack to use POP_STATE */
- childregs->CURRENT_TASK = (unsigned long)p;
- /* if returning to user then use the parent's value of this register */
-
- /* if we're creating a new kernel thread then just zeroing all
- * the registers. That's OK for a brand new thread.*/
- /* Pls. note that some of them will be restored in POP_STATE */
- if (kernel_mode(regs))
- memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
- /* if this thread is created for fork/vfork/clone, then we want to
- * restore all the parent's context */
- /* in addition to the registers which will be restored by POP_STATE */
- else {
- ti->cpu_context = *(struct cpu_context *)regs;
- childregs->msr |= MSR_UMS;
- }
-
- /* FIXME STATE_SAVE_PT_OFFSET; */
- ti->cpu_context.r1 = (unsigned long)childregs;
/* we should consider the fact that childregs is a copy of the parent
* regs which were saved immediately after entering the kernel state
* before enabling VM. This MSR will be restored in switch_to and
@@ -209,29 +202,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
}
#endif
-static void kernel_thread_helper(int (*fn)(void *), void *arg)
-{
- fn(arg);
- do_exit(-1);
-}
-
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
- /* store them in non-volatile registers */
- regs.r5 = (unsigned long)fn;
- regs.r6 = (unsigned long)arg;
- local_save_flags(regs.msr);
- regs.pc = (unsigned long)kernel_thread_helper;
- regs.pt_mode = 1;
-
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
- &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL_GPL(kernel_thread);
-
unsigned long get_wchan(struct task_struct *p)
{
/* TBD (used by procfs) */
@@ -246,6 +216,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
regs->pt_mode = 0;
#ifdef CONFIG_MMU
regs->msr |= MSR_UMS;
+ regs->msr &= ~MSR_VM;
#endif
}
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 3847e5b9c601..3903e3d11f5a 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1))
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT)
goto badframe;
return rval;
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 404c0f24bd41..63647c586b43 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -34,38 +34,6 @@
#include <asm/syscalls.h>
-asmlinkage long microblaze_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
- regs, 0, NULL, NULL);
-}
-
-asmlinkage long microblaze_clone(int flags, unsigned long stack,
- struct pt_regs *regs)
-{
- if (!stack)
- stack = regs->r1;
- return do_fork(flags, stack, regs, 0, NULL, NULL);
-}
-
-asmlinkage long microblaze_execve(const char __user *filenamei,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs)
-{
- int error;
- struct filename *filename;
-
- filename = getname(filenamei);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename->name, argv, envp, regs);
- putname(filename);
-out:
- return error;
-}
-
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, off_t pgoff)
@@ -75,24 +43,3 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
}
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- register const char *__a __asm__("r5") = filename;
- register const void *__b __asm__("r6") = argv;
- register const void *__c __asm__("r7") = envp;
- register unsigned long __syscall __asm__("r12") = __NR_execve;
- register unsigned long __ret __asm__("r3");
- __asm__ __volatile__ ("brki r14, 0x8"
- : "=r" (__ret), "=r" (__syscall)
- : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
- : "r4", "r8", "r9",
- "r10", "r11", "r14", "cc", "memory");
- return __ret;
-}
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 6a2b294ef6dc..ff6431e54680 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -2,11 +2,7 @@ ENTRY(sys_call_table)
.long sys_restart_syscall /* 0 - old "setup()" system call,
* used for restarting */
.long sys_exit
-#ifdef CONFIG_MMU
- .long sys_fork_wrapper
-#else
- .long sys_ni_syscall
-#endif
+ .long sys_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 4dbb5055d04b..a1c5b996d66d 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -1346,8 +1346,6 @@ void __init pcibios_resource_survey(void)
pci_assign_unassigned_resources();
}
-#ifdef CONFIG_HOTPLUG
-
/* This is used by the PCI hotplug driver to allocate resource
* of newly plugged busses. We can try to consolidate with the
* rest of the code later, for now, keep it as-is as our main
@@ -1407,8 +1405,6 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
-#endif /* CONFIG_HOTPLUG */
-
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
return pci_enable_resources(dev, mask);
OpenPOWER on IntegriCloud