aboutsummaryrefslogtreecommitdiffstats
path: root/arch/unicore32/kernel
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/unicore32/kernel
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/unicore32/kernel')
-rw-r--r--arch/unicore32/kernel/Makefile3
-rw-r--r--arch/unicore32/kernel/dma.c1
-rw-r--r--arch/unicore32/kernel/entry.S28
-rw-r--r--arch/unicore32/kernel/head.S2
-rw-r--r--arch/unicore32/kernel/hibernate.c1
-rw-r--r--arch/unicore32/kernel/irq.c1
-rw-r--r--arch/unicore32/kernel/ksyms.c5
-rw-r--r--arch/unicore32/kernel/module.c3
-rw-r--r--arch/unicore32/kernel/pci.c24
-rw-r--r--arch/unicore32/kernel/process.c72
-rw-r--r--arch/unicore32/kernel/puv3-core.c1
-rw-r--r--arch/unicore32/kernel/puv3-nb0916.c5
-rw-r--r--arch/unicore32/kernel/setup.c3
-rw-r--r--arch/unicore32/kernel/setup.h9
-rw-r--r--arch/unicore32/kernel/signal.c69
-rw-r--r--arch/unicore32/kernel/sys.c78
-rw-r--r--arch/unicore32/kernel/time.c2
-rw-r--r--arch/unicore32/kernel/traps.c1
18 files changed, 240 insertions, 68 deletions
diff --git a/arch/unicore32/kernel/Makefile b/arch/unicore32/kernel/Makefile
index fa497e0efe5..aeb0f181568 100644
--- a/arch/unicore32/kernel/Makefile
+++ b/arch/unicore32/kernel/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o
16obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o 16obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o
17 17
18obj-$(CONFIG_PUV3_GPIO) += gpio.o 18obj-$(CONFIG_PUV3_GPIO) += gpio.o
19obj-$(CONFIG_PUV3_PWM) += pwm.o
19obj-$(CONFIG_PUV3_PM) += pm.o sleep.o 20obj-$(CONFIG_PUV3_PM) += pm.o sleep.o
20obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o 21obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o
21 22
@@ -28,4 +29,4 @@ obj-$(CONFIG_PUV3_NB0916) += puv3-nb0916.o
28head-y := head.o 29head-y := head.o
29obj-$(CONFIG_DEBUG_LL) += debug.o 30obj-$(CONFIG_DEBUG_LL) += debug.o
30 31
31extra-y := $(head-y) vmlinux.lds 32extra-y := $(head-y) init_task.o vmlinux.lds
diff --git a/arch/unicore32/kernel/dma.c b/arch/unicore32/kernel/dma.c
index ed2d4d78d9c..ae441bc3122 100644
--- a/arch/unicore32/kernel/dma.c
+++ b/arch/unicore32/kernel/dma.c
@@ -18,6 +18,7 @@
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/io.h> 19#include <linux/io.h>
20 20
21#include <asm/system.h>
21#include <asm/irq.h> 22#include <asm/irq.h>
22#include <mach/hardware.h> 23#include <mach/hardware.h>
23#include <mach/dma.h> 24#include <mach/dma.h>
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S
index 581630d9144..00a259f9819 100644
--- a/arch/unicore32/kernel/entry.S
+++ b/arch/unicore32/kernel/entry.S
@@ -544,6 +544,8 @@ fast_work_pending:
544work_pending: 544work_pending:
545 cand.a r1, #_TIF_NEED_RESCHED 545 cand.a r1, #_TIF_NEED_RESCHED
546 bne work_resched 546 bne work_resched
547 cand.a r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
548 beq no_work_pending
547 mov r0, sp @ 'regs' 549 mov r0, sp @ 'regs'
548 mov r2, why @ 'syscall' 550 mov r2, why @ 'syscall'
549 cand.a r1, #_TIF_SIGPENDING @ delivering a signal? 551 cand.a r1, #_TIF_SIGPENDING @ delivering a signal?
@@ -573,16 +575,17 @@ ENDPROC(ret_to_user)
573 */ 575 */
574ENTRY(ret_from_fork) 576ENTRY(ret_from_fork)
575 b.l schedule_tail 577 b.l schedule_tail
578 get_thread_info tsk
579 ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing
580 mov why, #1
581 cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
582 beq ret_slow_syscall
583 mov r1, sp
584 mov r0, #1 @ trace exit [IP = 1]
585 b.l syscall_trace
576 b ret_slow_syscall 586 b ret_slow_syscall
577ENDPROC(ret_from_fork) 587ENDPROC(ret_from_fork)
578 588
579ENTRY(ret_from_kernel_thread)
580 b.l schedule_tail
581 mov r0, r5
582 adr lr, ret_slow_syscall
583 mov pc, r4
584ENDPROC(ret_from_kernel_thread)
585
586/*============================================================================= 589/*=============================================================================
587 * SWI handler 590 * SWI handler
588 *----------------------------------------------------------------------------- 591 *-----------------------------------------------------------------------------
@@ -668,6 +671,17 @@ __cr_alignment:
668#endif 671#endif
669 .ltorg 672 .ltorg
670 673
674ENTRY(sys_execve)
675 add r3, sp, #S_OFF
676 b __sys_execve
677ENDPROC(sys_execve)
678
679ENTRY(sys_clone)
680 add ip, sp, #S_OFF
681 stw ip, [sp+], #4
682 b __sys_clone
683ENDPROC(sys_clone)
684
671ENTRY(sys_rt_sigreturn) 685ENTRY(sys_rt_sigreturn)
672 add r0, sp, #S_OFF 686 add r0, sp, #S_OFF
673 mov why, #0 @ prevent syscall restart handling 687 mov why, #0 @ prevent syscall restart handling
diff --git a/arch/unicore32/kernel/head.S b/arch/unicore32/kernel/head.S
index e8f0b98c02e..8caf322e110 100644
--- a/arch/unicore32/kernel/head.S
+++ b/arch/unicore32/kernel/head.S
@@ -17,7 +17,7 @@
17#include <generated/asm-offsets.h> 17#include <generated/asm-offsets.h>
18#include <asm/memory.h> 18#include <asm/memory.h>
19#include <asm/thread_info.h> 19#include <asm/thread_info.h>
20#include <asm/hwdef-copro.h> 20#include <asm/system.h>
21#include <asm/pgtable-hwdef.h> 21#include <asm/pgtable-hwdef.h>
22 22
23#if (PHYS_OFFSET & 0x003fffff) 23#if (PHYS_OFFSET & 0x003fffff)
diff --git a/arch/unicore32/kernel/hibernate.c b/arch/unicore32/kernel/hibernate.c
index d75ef8b6cb5..7d0f0b7983a 100644
--- a/arch/unicore32/kernel/hibernate.c
+++ b/arch/unicore32/kernel/hibernate.c
@@ -15,6 +15,7 @@
15#include <linux/suspend.h> 15#include <linux/suspend.h>
16#include <linux/bootmem.h> 16#include <linux/bootmem.h>
17 17
18#include <asm/system.h>
18#include <asm/page.h> 19#include <asm/page.h>
19#include <asm/pgtable.h> 20#include <asm/pgtable.h>
20#include <asm/pgalloc.h> 21#include <asm/pgalloc.h>
diff --git a/arch/unicore32/kernel/irq.c b/arch/unicore32/kernel/irq.c
index 0be5ccd7ccd..d4efa7d679f 100644
--- a/arch/unicore32/kernel/irq.c
+++ b/arch/unicore32/kernel/irq.c
@@ -26,6 +26,7 @@
26#include <linux/syscore_ops.h> 26#include <linux/syscore_ops.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28 28
29#include <asm/system.h>
29#include <mach/hardware.h> 30#include <mach/hardware.h>
30 31
31#include "setup.h" 32#include "setup.h"
diff --git a/arch/unicore32/kernel/ksyms.c b/arch/unicore32/kernel/ksyms.c
index d285d71cbe3..a8970809428 100644
--- a/arch/unicore32/kernel/ksyms.c
+++ b/arch/unicore32/kernel/ksyms.c
@@ -20,11 +20,12 @@
20#include <linux/io.h> 20#include <linux/io.h>
21 21
22#include <asm/checksum.h> 22#include <asm/checksum.h>
23#include <asm/system.h>
23 24
24#include "ksyms.h" 25#include "ksyms.h"
25 26
26EXPORT_SYMBOL(find_next_zero_bit); 27EXPORT_SYMBOL(__uc32_find_next_zero_bit);
27EXPORT_SYMBOL(find_next_bit); 28EXPORT_SYMBOL(__uc32_find_next_bit);
28 29
29EXPORT_SYMBOL(__backtrace); 30EXPORT_SYMBOL(__backtrace);
30 31
diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c
index 16bd1495b93..8fbe8577f5e 100644
--- a/arch/unicore32/kernel/module.c
+++ b/arch/unicore32/kernel/module.c
@@ -27,6 +27,9 @@ void *module_alloc(unsigned long size)
27 struct vm_struct *area; 27 struct vm_struct *area;
28 28
29 size = PAGE_ALIGN(size); 29 size = PAGE_ALIGN(size);
30 if (!size)
31 return NULL;
32
30 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); 33 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
31 if (!area) 34 if (!area)
32 return NULL; 35 return NULL;
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index ef69c0c8282..4892fbb54eb 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -21,6 +21,7 @@
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23static int debug_pci; 23static int debug_pci;
24static int use_firmware;
24 25
25#define CONFIG_CMD(bus, devfn, where) \ 26#define CONFIG_CMD(bus, devfn, where) \
26 (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) 27 (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
@@ -154,6 +155,14 @@ void __init puv3_pci_adjust_zones(unsigned long *zone_size,
154 zhole_size[0] = 0; 155 zhole_size[0] = 0;
155} 156}
156 157
158void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
159{
160 if (debug_pci)
161 printk(KERN_DEBUG "PCI: Assigning IRQ %02d to %s\n",
162 irq, pci_name(dev));
163 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
164}
165
157/* 166/*
158 * If the bus contains any of these devices, then we must not turn on 167 * If the bus contains any of these devices, then we must not turn on
159 * parity checking of any kind. 168 * parity checking of any kind.
@@ -167,7 +176,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev)
167 * pcibios_fixup_bus - Called after each bus is probed, 176 * pcibios_fixup_bus - Called after each bus is probed,
168 * but before its children are examined. 177 * but before its children are examined.
169 */ 178 */
170void pcibios_fixup_bus(struct pci_bus *bus) 179void __devinit pcibios_fixup_bus(struct pci_bus *bus)
171{ 180{
172 struct pci_dev *dev; 181 struct pci_dev *dev;
173 u16 features = PCI_COMMAND_SERR 182 u16 features = PCI_COMMAND_SERR
@@ -250,7 +259,9 @@ void pcibios_fixup_bus(struct pci_bus *bus)
250 printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", 259 printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
251 bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); 260 bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
252} 261}
262#ifdef CONFIG_HOTPLUG
253EXPORT_SYMBOL(pcibios_fixup_bus); 263EXPORT_SYMBOL(pcibios_fixup_bus);
264#endif
254 265
255static int __init pci_common_init(void) 266static int __init pci_common_init(void)
256{ 267{
@@ -265,7 +276,7 @@ static int __init pci_common_init(void)
265 276
266 pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); 277 pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq);
267 278
268 if (!pci_has_flag(PCI_PROBE_ONLY)) { 279 if (!use_firmware) {
269 /* 280 /*
270 * Size the bridge windows. 281 * Size the bridge windows.
271 */ 282 */
@@ -286,23 +297,18 @@ static int __init pci_common_init(void)
286} 297}
287subsys_initcall(pci_common_init); 298subsys_initcall(pci_common_init);
288 299
289char * __init pcibios_setup(char *str) 300char * __devinit pcibios_setup(char *str)
290{ 301{
291 if (!strcmp(str, "debug")) { 302 if (!strcmp(str, "debug")) {
292 debug_pci = 1; 303 debug_pci = 1;
293 return NULL; 304 return NULL;
294 } else if (!strcmp(str, "firmware")) { 305 } else if (!strcmp(str, "firmware")) {
295 pci_add_flags(PCI_PROBE_ONLY); 306 use_firmware = 1;
296 return NULL; 307 return NULL;
297 } 308 }
298 return str; 309 return str;
299} 310}
300 311
301void pcibios_set_master(struct pci_dev *dev)
302{
303 /* No special bus mastering setup handling */
304}
305
306/* 312/*
307 * From arch/i386/kernel/pci-i386.c: 313 * From arch/i386/kernel/pci-i386.c:
308 * 314 *
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index 62bad9fed03..ba401df971e 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -34,6 +34,7 @@
34 34
35#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
36#include <asm/processor.h> 36#include <asm/processor.h>
37#include <asm/system.h>
37#include <asm/stacktrace.h> 38#include <asm/stacktrace.h>
38 39
39#include "setup.h" 40#include "setup.h"
@@ -54,8 +55,7 @@ void cpu_idle(void)
54{ 55{
55 /* endless idle loop with no priority at all */ 56 /* endless idle loop with no priority at all */
56 while (1) { 57 while (1) {
57 tick_nohz_idle_enter(); 58 tick_nohz_stop_sched_tick(1);
58 rcu_idle_enter();
59 while (!need_resched()) { 59 while (!need_resched()) {
60 local_irq_disable(); 60 local_irq_disable();
61 stop_critical_timings(); 61 stop_critical_timings();
@@ -63,8 +63,7 @@ void cpu_idle(void)
63 local_irq_enable(); 63 local_irq_enable();
64 start_critical_timings(); 64 start_critical_timings();
65 } 65 }
66 rcu_idle_exit(); 66 tick_nohz_restart_sched_tick();
67 tick_nohz_idle_exit();
68 preempt_enable_no_resched(); 67 preempt_enable_no_resched();
69 schedule(); 68 schedule();
70 preempt_disable(); 69 preempt_disable();
@@ -258,32 +257,25 @@ void release_thread(struct task_struct *dead_task)
258} 257}
259 258
260asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 259asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
261asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
262 260
263int 261int
264copy_thread(unsigned long clone_flags, unsigned long stack_start, 262copy_thread(unsigned long clone_flags, unsigned long stack_start,
265 unsigned long stk_sz, struct task_struct *p) 263 unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
266{ 264{
267 struct thread_info *thread = task_thread_info(p); 265 struct thread_info *thread = task_thread_info(p);
268 struct pt_regs *childregs = task_pt_regs(p); 266 struct pt_regs *childregs = task_pt_regs(p);
269 267
268 *childregs = *regs;
269 childregs->UCreg_00 = 0;
270 childregs->UCreg_sp = stack_start;
271
270 memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); 272 memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
271 thread->cpu_context.sp = (unsigned long)childregs; 273 thread->cpu_context.sp = (unsigned long)childregs;
272 if (unlikely(p->flags & PF_KTHREAD)) { 274 thread->cpu_context.pc = (unsigned long)ret_from_fork;
273 thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; 275
274 thread->cpu_context.r4 = stack_start; 276 if (clone_flags & CLONE_SETTLS)
275 thread->cpu_context.r5 = stk_sz; 277 childregs->UCreg_16 = regs->UCreg_03;
276 memset(childregs, 0, sizeof(struct pt_regs)); 278
277 } else {
278 thread->cpu_context.pc = (unsigned long)ret_from_fork;
279 *childregs = *current_pt_regs();
280 childregs->UCreg_00 = 0;
281 if (stack_start)
282 childregs->UCreg_sp = stack_start;
283
284 if (clone_flags & CLONE_SETTLS)
285 childregs->UCreg_16 = childregs->UCreg_03;
286 }
287 return 0; 279 return 0;
288} 280}
289 281
@@ -312,6 +304,42 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp)
312} 304}
313EXPORT_SYMBOL(dump_fpu); 305EXPORT_SYMBOL(dump_fpu);
314 306
307/*
308 * Shuffle the argument into the correct register before calling the
309 * thread function. r1 is the thread argument, r2 is the pointer to
310 * the thread function, and r3 points to the exit function.
311 */
312asm(".pushsection .text\n"
313" .align\n"
314" .type kernel_thread_helper, #function\n"
315"kernel_thread_helper:\n"
316" mov.a asr, r7\n"
317" mov r0, r4\n"
318" mov lr, r6\n"
319" mov pc, r5\n"
320" .size kernel_thread_helper, . - kernel_thread_helper\n"
321" .popsection");
322
323/*
324 * Create a kernel thread.
325 */
326pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
327{
328 struct pt_regs regs;
329
330 memset(&regs, 0, sizeof(regs));
331
332 regs.UCreg_04 = (unsigned long)arg;
333 regs.UCreg_05 = (unsigned long)fn;
334 regs.UCreg_06 = (unsigned long)do_exit;
335 regs.UCreg_07 = PRIV_MODE;
336 regs.UCreg_pc = (unsigned long)kernel_thread_helper;
337 regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT;
338
339 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
340}
341EXPORT_SYMBOL(kernel_thread);
342
315unsigned long get_wchan(struct task_struct *p) 343unsigned long get_wchan(struct task_struct *p)
316{ 344{
317 struct stackframe frame; 345 struct stackframe frame;
@@ -351,7 +379,7 @@ int vectors_user_mapping(void)
351 return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, 379 return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
352 VM_READ | VM_EXEC | 380 VM_READ | VM_EXEC |
353 VM_MAYREAD | VM_MAYEXEC | 381 VM_MAYREAD | VM_MAYEXEC |
354 VM_DONTEXPAND | VM_DONTDUMP, 382 VM_ALWAYSDUMP | VM_RESERVED,
355 NULL); 383 NULL);
356} 384}
357 385
diff --git a/arch/unicore32/kernel/puv3-core.c b/arch/unicore32/kernel/puv3-core.c
index 254adeecc61..1a505a78776 100644
--- a/arch/unicore32/kernel/puv3-core.c
+++ b/arch/unicore32/kernel/puv3-core.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/sysdev.h>
16#include <linux/amba/bus.h> 17#include <linux/amba/bus.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/io.h> 19#include <linux/io.h>
diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c
index 181108b8ecc..e731c561ed4 100644
--- a/arch/unicore32/kernel/puv3-nb0916.c
+++ b/arch/unicore32/kernel/puv3-nb0916.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/sysdev.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/mtd/physmap.h> 18#include <linux/mtd/physmap.h>
18#include <linux/io.h> 19#include <linux/io.h>
@@ -123,7 +124,7 @@ int __init mach_nb0916_init(void)
123 124
124 if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF), 125 if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF),
125 &nb0916_lcdcaseoff_handler, 126 &nb0916_lcdcaseoff_handler,
126 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 127 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
127 "NB0916 lcd case off", NULL) < 0) { 128 "NB0916 lcd case off", NULL) < 0) {
128 129
129 printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n", 130 printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n",
@@ -131,7 +132,7 @@ int __init mach_nb0916_init(void)
131 } 132 }
132 133
133 if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler, 134 if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler,
134 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 135 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
135 "NB0916 overheating protection", NULL) < 0) { 136 "NB0916 overheating protection", NULL) < 0) {
136 137
137 printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n", 138 printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n",
diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c
index 87adbf5ebfe..471b6bca8da 100644
--- a/arch/unicore32/kernel/setup.c
+++ b/arch/unicore32/kernel/setup.c
@@ -37,7 +37,6 @@
37#include <asm/cacheflush.h> 37#include <asm/cacheflush.h>
38#include <asm/tlbflush.h> 38#include <asm/tlbflush.h>
39#include <asm/traps.h> 39#include <asm/traps.h>
40#include <asm/memblock.h>
41 40
42#include "setup.h" 41#include "setup.h"
43 42
@@ -65,7 +64,7 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
65 */ 64 */
66static struct resource mem_res[] = { 65static struct resource mem_res[] = {
67 { 66 {
68 .name = "Kernel code", 67 .name = "Kernel text",
69 .start = 0, 68 .start = 0,
70 .end = 0, 69 .end = 0,
71 .flags = IORESOURCE_MEM 70 .flags = IORESOURCE_MEM
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h
index 30f749da8f7..dcd1306eb5c 100644
--- a/arch/unicore32/kernel/setup.h
+++ b/arch/unicore32/kernel/setup.h
@@ -12,11 +12,8 @@
12#ifndef __UNICORE_KERNEL_SETUP_H__ 12#ifndef __UNICORE_KERNEL_SETUP_H__
13#define __UNICORE_KERNEL_SETUP_H__ 13#define __UNICORE_KERNEL_SETUP_H__
14 14
15#include <asm/hwdef-copro.h>
16
17extern void paging_init(void); 15extern void paging_init(void);
18extern void puv3_core_init(void); 16extern void puv3_core_init(void);
19extern void cpu_init(void);
20 17
21extern void puv3_ps2_init(void); 18extern void puv3_ps2_init(void);
22extern void pci_puv3_preinit(void); 19extern void pci_puv3_preinit(void);
@@ -30,10 +27,4 @@ extern char __vectors_start[], __vectors_end[];
30extern void kernel_thread_helper(void); 27extern void kernel_thread_helper(void);
31 28
32extern void __init early_signal_init(void); 29extern void __init early_signal_init(void);
33
34extern asmlinkage void __backtrace(void);
35extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
36
37extern void __show_regs(struct pt_regs *);
38
39#endif 30#endif
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index b8b2ffd774d..b163fca5678 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -12,6 +12,7 @@
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/signal.h> 13#include <linux/signal.h>
14#include <linux/personality.h> 14#include <linux/personality.h>
15#include <linux/freezer.h>
15#include <linux/uaccess.h> 16#include <linux/uaccess.h>
16#include <linux/tracehook.h> 17#include <linux/tracehook.h>
17#include <linux/elf.h> 18#include <linux/elf.h>
@@ -20,6 +21,8 @@
20#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
21#include <asm/ucontext.h> 22#include <asm/ucontext.h>
22 23
24#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
25
23/* 26/*
24 * For UniCore syscalls, we encode the syscall number into the instruction. 27 * For UniCore syscalls, we encode the syscall number into the instruction.
25 */ 28 */
@@ -58,8 +61,13 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
58 int err; 61 int err;
59 62
60 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); 63 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
61 if (err == 0) 64 if (err == 0) {
62 set_current_blocked(&set); 65 sigdelsetmask(&set, ~_BLOCKABLE);
66 spin_lock_irq(&current->sighand->siglock);
67 current->blocked = set;
68 recalc_sigpending();
69 spin_unlock_irq(&current->sighand->siglock);
70 }
63 71
64 err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00); 72 err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00);
65 err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01); 73 err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01);
@@ -307,12 +315,12 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
307/* 315/*
308 * OK, we're invoking a handler 316 * OK, we're invoking a handler
309 */ 317 */
310static void handle_signal(unsigned long sig, struct k_sigaction *ka, 318static int handle_signal(unsigned long sig, struct k_sigaction *ka,
311 siginfo_t *info, struct pt_regs *regs, int syscall) 319 siginfo_t *info, sigset_t *oldset,
320 struct pt_regs *regs, int syscall)
312{ 321{
313 struct thread_info *thread = current_thread_info(); 322 struct thread_info *thread = current_thread_info();
314 struct task_struct *tsk = current; 323 struct task_struct *tsk = current;
315 sigset_t *oldset = sigmask_to_save();
316 int usig = sig; 324 int usig = sig;
317 int ret; 325 int ret;
318 326
@@ -358,10 +366,21 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
358 366
359 if (ret != 0) { 367 if (ret != 0) {
360 force_sigsegv(sig, tsk); 368 force_sigsegv(sig, tsk);
361 return; 369 return ret;
362 } 370 }
363 371
364 signal_delivered(sig, info, ka, regs, 0); 372 /*
373 * Block the signal if we were successful.
374 */
375 spin_lock_irq(&tsk->sighand->siglock);
376 sigorsets(&tsk->blocked, &tsk->blocked,
377 &ka->sa.sa_mask);
378 if (!(ka->sa.sa_flags & SA_NODEFER))
379 sigaddset(&tsk->blocked, sig);
380 recalc_sigpending();
381 spin_unlock_irq(&tsk->sighand->siglock);
382
383 return 0;
365} 384}
366 385
367/* 386/*
@@ -388,12 +407,32 @@ static void do_signal(struct pt_regs *regs, int syscall)
388 if (!user_mode(regs)) 407 if (!user_mode(regs))
389 return; 408 return;
390 409
410 if (try_to_freeze())
411 goto no_signal;
412
391 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 413 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
392 if (signr > 0) { 414 if (signr > 0) {
393 handle_signal(signr, &ka, &info, regs, syscall); 415 sigset_t *oldset;
416
417 if (test_thread_flag(TIF_RESTORE_SIGMASK))
418 oldset = &current->saved_sigmask;
419 else
420 oldset = &current->blocked;
421 if (handle_signal(signr, &ka, &info, oldset, regs, syscall)
422 == 0) {
423 /*
424 * A signal was successfully delivered; the saved
425 * sigmask will have been stored in the signal frame,
426 * and will be restored by sigreturn, so we can simply
427 * clear the TIF_RESTORE_SIGMASK flag.
428 */
429 if (test_thread_flag(TIF_RESTORE_SIGMASK))
430 clear_thread_flag(TIF_RESTORE_SIGMASK);
431 }
394 return; 432 return;
395 } 433 }
396 434
435 no_signal:
397 /* 436 /*
398 * No signal to deliver to the process - restart the syscall. 437 * No signal to deliver to the process - restart the syscall.
399 */ 438 */
@@ -416,11 +455,15 @@ static void do_signal(struct pt_regs *regs, int syscall)
416 regs->UCreg_00 == -ERESTARTNOINTR) { 455 regs->UCreg_00 == -ERESTARTNOINTR) {
417 setup_syscall_restart(regs); 456 setup_syscall_restart(regs);
418 } 457 }
458
459 /* If there's no signal to deliver, we just put the saved
460 * sigmask back.
461 */
462 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
463 clear_thread_flag(TIF_RESTORE_SIGMASK);
464 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
465 }
419 } 466 }
420 /* If there's no signal to deliver, we just put the saved
421 * sigmask back.
422 */
423 restore_saved_sigmask();
424} 467}
425 468
426asmlinkage void do_notify_resume(struct pt_regs *regs, 469asmlinkage void do_notify_resume(struct pt_regs *regs,
@@ -432,6 +475,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
432 if (thread_flags & _TIF_NOTIFY_RESUME) { 475 if (thread_flags & _TIF_NOTIFY_RESUME) {
433 clear_thread_flag(TIF_NOTIFY_RESUME); 476 clear_thread_flag(TIF_NOTIFY_RESUME);
434 tracehook_notify_resume(regs); 477 tracehook_notify_resume(regs);
478 if (current->replacement_session_keyring)
479 key_replace_session_keyring();
435 } 480 }
436} 481}
437 482
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
index cfe79c9529b..3afe60a39ac 100644
--- a/arch/unicore32/kernel/sys.c
+++ b/arch/unicore32/kernel/sys.c
@@ -28,6 +28,84 @@
28#include <asm/syscalls.h> 28#include <asm/syscalls.h>
29#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
30 30
31/* Clone a task - this clones the calling program thread.
32 * This is called indirectly via a small wrapper
33 */
34asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
35 void __user *parent_tid, void __user *child_tid,
36 struct pt_regs *regs)
37{
38 if (!newsp)
39 newsp = regs->UCreg_sp;
40
41 return do_fork(clone_flags, newsp, regs, 0,
42 parent_tid, child_tid);
43}
44
45/* sys_execve() executes a new program.
46 * This is called indirectly via a small wrapper
47 */
48asmlinkage long __sys_execve(const char __user *filename,
49 const char __user *const __user *argv,
50 const char __user *const __user *envp,
51 struct pt_regs *regs)
52{
53 int error;
54 char *fn;
55
56 fn = getname(filename);
57 error = PTR_ERR(fn);
58 if (IS_ERR(fn))
59 goto out;
60 error = do_execve(fn, argv, envp, regs);
61 putname(fn);
62out:
63 return error;
64}
65
66int kernel_execve(const char *filename,
67 const char *const argv[],
68 const char *const envp[])
69{
70 struct pt_regs regs;
71 int ret;
72
73 memset(&regs, 0, sizeof(struct pt_regs));
74 ret = do_execve(filename,
75 (const char __user *const __user *)argv,
76 (const char __user *const __user *)envp, &regs);
77 if (ret < 0)
78 goto out;
79
80 /*
81 * Save argc to the register structure for userspace.
82 */
83 regs.UCreg_00 = ret;
84
85 /*
86 * We were successful. We won't be returning to our caller, but
87 * instead to user space by manipulating the kernel stack.
88 */
89 asm("add r0, %0, %1\n\t"
90 "mov r1, %2\n\t"
91 "mov r2, %3\n\t"
92 "mov r22, #0\n\t" /* not a syscall */
93 "mov r23, %0\n\t" /* thread structure */
94 "b.l memmove\n\t" /* copy regs to top of stack */
95 "mov sp, r0\n\t" /* reposition stack pointer */
96 "b ret_to_user"
97 :
98 : "r" (current_thread_info()),
99 "Ir" (THREAD_START_SP - sizeof(regs)),
100 "r" (&regs),
101 "Ir" (sizeof(regs))
102 : "r0", "r1", "r2", "r3", "ip", "lr", "memory");
103
104 out:
105 return ret;
106}
107EXPORT_SYMBOL(kernel_execve);
108
31/* Note: used by the compat code even in 64-bit Linux. */ 109/* Note: used by the compat code even in 64-bit Linux. */
32SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, 110SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
33 unsigned long, prot, unsigned long, flags, 111 unsigned long, prot, unsigned long, flags,
diff --git a/arch/unicore32/kernel/time.c b/arch/unicore32/kernel/time.c
index d3824b2ff64..080710c0924 100644
--- a/arch/unicore32/kernel/time.c
+++ b/arch/unicore32/kernel/time.c
@@ -86,7 +86,7 @@ static struct clocksource cksrc_puv3_oscr = {
86 86
87static struct irqaction puv3_timer_irq = { 87static struct irqaction puv3_timer_irq = {
88 .name = "ost0", 88 .name = "ost0",
89 .flags = IRQF_TIMER | IRQF_IRQPOLL, 89 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
90 .handler = puv3_ost0_interrupt, 90 .handler = puv3_ost0_interrupt,
91 .dev_id = &ckevt_puv3_osmr0, 91 .dev_id = &ckevt_puv3_osmr0,
92}; 92};
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c
index 2054f0d4db1..b9a26465e72 100644
--- a/arch/unicore32/kernel/traps.c
+++ b/arch/unicore32/kernel/traps.c
@@ -26,6 +26,7 @@
26#include <linux/unistd.h> 26#include <linux/unistd.h>
27 27
28#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
29#include <asm/system.h>
29#include <asm/traps.h> 30#include <asm/traps.h>
30 31
31#include "setup.h" 32#include "setup.h"