]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - arch/nios2/kernel/process.c
2 * Architecture-dependent parts of process handling.
4 * Copyright (C) 2013 Altera Corporation
5 * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
6 * Copyright (C) 2009 Wind River Systems Inc
7 * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
8 * Copyright (C) 2004 Microtronix Datacom Ltd
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
15 #include <linux/export.h>
16 #include <linux/sched.h>
17 #include <linux/sched/debug.h>
18 #include <linux/sched/task.h>
19 #include <linux/tick.h>
20 #include <linux/uaccess.h>
22 #include <asm/unistd.h>
23 #include <asm/traps.h>
24 #include <asm/cpuinfo.h>
26 asmlinkage
void ret_from_fork(void);
27 asmlinkage
void ret_from_kernel_thread(void);
29 void (*pm_power_off
)(void) = NULL
;
30 EXPORT_SYMBOL(pm_power_off
);
32 void arch_cpu_idle(void)
38 * The development boards have no way to pull a board reset. Just jump to the
39 * cpu reset address and let the boot loader or the code in head.S take care of
40 * resetting peripherals.
42 void machine_restart(char *__unused
)
44 pr_notice("Machine restart (%08x)...\n", cpuinfo
.reset_addr
);
46 __asm__
__volatile__ (
49 : "r" (cpuinfo
.reset_addr
)
53 void machine_halt(void)
55 pr_notice("Machine halt...\n");
62 * There is no way to power off the development boards. So just spin for now. If
63 * we ever have a way of resetting a board using a GPIO we should add that here.
65 void machine_power_off(void)
67 pr_notice("Machine power off...\n");
73 void show_regs(struct pt_regs
*regs
)
76 show_regs_print_info(KERN_DEFAULT
);
78 pr_notice("r1: %08lx r2: %08lx r3: %08lx r4: %08lx\n",
79 regs
->r1
, regs
->r2
, regs
->r3
, regs
->r4
);
81 pr_notice("r5: %08lx r6: %08lx r7: %08lx r8: %08lx\n",
82 regs
->r5
, regs
->r6
, regs
->r7
, regs
->r8
);
84 pr_notice("r9: %08lx r10: %08lx r11: %08lx r12: %08lx\n",
85 regs
->r9
, regs
->r10
, regs
->r11
, regs
->r12
);
87 pr_notice("r13: %08lx r14: %08lx r15: %08lx\n",
88 regs
->r13
, regs
->r14
, regs
->r15
);
90 pr_notice("ra: %08lx fp: %08lx sp: %08lx gp: %08lx\n",
91 regs
->ra
, regs
->fp
, regs
->sp
, regs
->gp
);
93 pr_notice("ea: %08lx estatus: %08lx\n",
94 regs
->ea
, regs
->estatus
);
97 void flush_thread(void)
101 int copy_thread(unsigned long clone_flags
,
102 unsigned long usp
, unsigned long arg
, struct task_struct
*p
)
104 struct pt_regs
*childregs
= task_pt_regs(p
);
105 struct pt_regs
*regs
;
106 struct switch_stack
*stack
;
107 struct switch_stack
*childstack
=
108 ((struct switch_stack
*)childregs
) - 1;
110 if (unlikely(p
->flags
& PF_KTHREAD
)) {
111 memset(childstack
, 0,
112 sizeof(struct switch_stack
) + sizeof(struct pt_regs
));
114 childstack
->r16
= usp
; /* fn */
115 childstack
->r17
= arg
;
116 childstack
->ra
= (unsigned long) ret_from_kernel_thread
;
117 childregs
->estatus
= STATUS_PIE
;
118 childregs
->sp
= (unsigned long) childstack
;
120 p
->thread
.ksp
= (unsigned long) childstack
;
121 p
->thread
.kregs
= childregs
;
125 regs
= current_pt_regs();
127 childregs
->r2
= 0; /* Set the return value for the child. */
130 stack
= ((struct switch_stack
*) regs
) - 1;
131 *childstack
= *stack
;
132 childstack
->ra
= (unsigned long)ret_from_fork
;
133 p
->thread
.kregs
= childregs
;
134 p
->thread
.ksp
= (unsigned long) childstack
;
139 /* Initialize tls register. */
140 if (clone_flags
& CLONE_SETTLS
)
141 childstack
->r23
= regs
->r8
;
147 * Generic dumping code. Used for panic and debug.
149 void dump(struct pt_regs
*fp
)
155 pr_emerg("\nCURRENT PROCESS:\n\n");
156 pr_emerg("COMM=%s PID=%d\n", current
->comm
, current
->pid
);
159 pr_emerg("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
160 (int) current
->mm
->start_code
,
161 (int) current
->mm
->end_code
,
162 (int) current
->mm
->start_data
,
163 (int) current
->mm
->end_data
,
164 (int) current
->mm
->end_data
,
165 (int) current
->mm
->brk
);
166 pr_emerg("USER-STACK=%08x KERNEL-STACK=%08x\n\n",
167 (int) current
->mm
->start_stack
,
168 (int)(((unsigned long) current
) + THREAD_SIZE
));
171 pr_emerg("PC: %08lx\n", fp
->ea
);
172 pr_emerg("SR: %08lx SP: %08lx\n",
173 (long) fp
->estatus
, (long) fp
);
175 pr_emerg("r1: %08lx r2: %08lx r3: %08lx\n",
176 fp
->r1
, fp
->r2
, fp
->r3
);
178 pr_emerg("r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
179 fp
->r4
, fp
->r5
, fp
->r6
, fp
->r7
);
180 pr_emerg("r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
181 fp
->r8
, fp
->r9
, fp
->r10
, fp
->r11
);
182 pr_emerg("r12: %08lx r13: %08lx r14: %08lx r15: %08lx\n",
183 fp
->r12
, fp
->r13
, fp
->r14
, fp
->r15
);
184 pr_emerg("or2: %08lx ra: %08lx fp: %08lx sp: %08lx\n",
185 fp
->orig_r2
, fp
->ra
, fp
->fp
, fp
->sp
);
186 pr_emerg("\nUSP: %08x TRAPFRAME: %08x\n",
187 (unsigned int) fp
->sp
, (unsigned int) fp
);
190 tp
= ((unsigned char *) fp
->ea
) - 0x20;
191 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x40); i
+= 4) {
193 pr_emerg("\n%08x: ", (int) (tp
+ i
));
194 pr_emerg("%08x ", (int) *sp
++);
198 pr_emerg("\nKERNEL STACK:");
199 tp
= ((unsigned char *) fp
) - 0x40;
200 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0xc0); i
+= 4) {
202 pr_emerg("\n%08x: ", (int) (tp
+ i
));
203 pr_emerg("%08x ", (int) *sp
++);
208 pr_emerg("\nUSER STACK:");
209 tp
= (unsigned char *) (fp
->sp
- 0x10);
210 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x80); i
+= 4) {
212 pr_emerg("\n%08x: ", (int) (tp
+ i
));
213 pr_emerg("%08x ", (int) *sp
++);
218 unsigned long get_wchan(struct task_struct
*p
)
220 unsigned long fp
, pc
;
221 unsigned long stack_page
;
224 if (!p
|| p
== current
|| p
->state
== TASK_RUNNING
)
227 stack_page
= (unsigned long)p
;
228 fp
= ((struct switch_stack
*)p
->thread
.ksp
)->fp
; /* ;dgt2 */
230 if (fp
< stack_page
+sizeof(struct task_struct
) ||
231 fp
>= 8184+stack_page
) /* ;dgt2;tmp */
233 pc
= ((unsigned long *)fp
)[1];
234 if (!in_sched_functions(pc
))
236 fp
= *(unsigned long *) fp
;
237 } while (count
++ < 16); /* ;dgt2;tmp */
242 * Do necessary setup to start up a newly executed thread.
243 * Will startup in user mode (status_extension = 0).
245 void start_thread(struct pt_regs
*regs
, unsigned long pc
, unsigned long sp
)
247 memset((void *) regs
, 0, sizeof(struct pt_regs
));
248 regs
->estatus
= ESTATUS_EPIE
| ESTATUS_EU
;
253 #include <linux/elfcore.h>
255 /* Fill in the FPU structure for a core dump. */
256 int dump_fpu(struct pt_regs
*regs
, elf_fpregset_t
*r
)
258 return 0; /* Nios2 has no FPU and thus no FPU registers */