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/tick.h>
18 #include <linux/uaccess.h>
20 #include <asm/unistd.h>
21 #include <asm/traps.h>
22 #include <asm/cpuinfo.h>
24 asmlinkage
void ret_from_fork(void);
25 asmlinkage
void ret_from_kernel_thread(void);
27 void (*pm_power_off
)(void) = NULL
;
28 EXPORT_SYMBOL(pm_power_off
);
30 void arch_cpu_idle(void)
36 * The development boards have no way to pull a board reset. Just jump to the
37 * cpu reset address and let the boot loader or the code in head.S take care of
38 * resetting peripherals.
40 void machine_restart(char *__unused
)
42 pr_notice("Machine restart (%08x)...\n", cpuinfo
.reset_addr
);
44 __asm__
__volatile__ (
47 : "r" (cpuinfo
.reset_addr
)
51 void machine_halt(void)
53 pr_notice("Machine halt...\n");
60 * There is no way to power off the development boards. So just spin for now. If
61 * we ever have a way of resetting a board using a GPIO we should add that here.
63 void machine_power_off(void)
65 pr_notice("Machine power off...\n");
71 void show_regs(struct pt_regs
*regs
)
74 show_regs_print_info(KERN_DEFAULT
);
76 pr_notice("r1: %08lx r2: %08lx r3: %08lx r4: %08lx\n",
77 regs
->r1
, regs
->r2
, regs
->r3
, regs
->r4
);
79 pr_notice("r5: %08lx r6: %08lx r7: %08lx r8: %08lx\n",
80 regs
->r5
, regs
->r6
, regs
->r7
, regs
->r8
);
82 pr_notice("r9: %08lx r10: %08lx r11: %08lx r12: %08lx\n",
83 regs
->r9
, regs
->r10
, regs
->r11
, regs
->r12
);
85 pr_notice("r13: %08lx r14: %08lx r15: %08lx\n",
86 regs
->r13
, regs
->r14
, regs
->r15
);
88 pr_notice("ra: %08lx fp: %08lx sp: %08lx gp: %08lx\n",
89 regs
->ra
, regs
->fp
, regs
->sp
, regs
->gp
);
91 pr_notice("ea: %08lx estatus: %08lx\n",
92 regs
->ea
, regs
->estatus
);
95 void flush_thread(void)
100 int copy_thread(unsigned long clone_flags
,
101 unsigned long usp
, unsigned long arg
, struct task_struct
*p
)
103 struct pt_regs
*childregs
= task_pt_regs(p
);
104 struct pt_regs
*regs
;
105 struct switch_stack
*stack
;
106 struct switch_stack
*childstack
=
107 ((struct switch_stack
*)childregs
) - 1;
109 if (unlikely(p
->flags
& PF_KTHREAD
)) {
110 memset(childstack
, 0,
111 sizeof(struct switch_stack
) + sizeof(struct pt_regs
));
113 childstack
->r16
= usp
; /* fn */
114 childstack
->r17
= arg
;
115 childstack
->ra
= (unsigned long) ret_from_kernel_thread
;
116 childregs
->estatus
= STATUS_PIE
;
117 childregs
->sp
= (unsigned long) childstack
;
119 p
->thread
.ksp
= (unsigned long) childstack
;
120 p
->thread
.kregs
= childregs
;
124 regs
= current_pt_regs();
126 childregs
->r2
= 0; /* Set the return value for the child. */
129 stack
= ((struct switch_stack
*) regs
) - 1;
130 *childstack
= *stack
;
131 childstack
->ra
= (unsigned long)ret_from_fork
;
132 p
->thread
.kregs
= childregs
;
133 p
->thread
.ksp
= (unsigned long) childstack
;
138 /* Initialize tls register. */
139 if (clone_flags
& CLONE_SETTLS
)
140 childstack
->r23
= regs
->r8
;
146 * Generic dumping code. Used for panic and debug.
148 void dump(struct pt_regs
*fp
)
154 pr_emerg("\nCURRENT PROCESS:\n\n");
155 pr_emerg("COMM=%s PID=%d\n", current
->comm
, current
->pid
);
158 pr_emerg("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
159 (int) current
->mm
->start_code
,
160 (int) current
->mm
->end_code
,
161 (int) current
->mm
->start_data
,
162 (int) current
->mm
->end_data
,
163 (int) current
->mm
->end_data
,
164 (int) current
->mm
->brk
);
165 pr_emerg("USER-STACK=%08x KERNEL-STACK=%08x\n\n",
166 (int) current
->mm
->start_stack
,
167 (int)(((unsigned long) current
) + THREAD_SIZE
));
170 pr_emerg("PC: %08lx\n", fp
->ea
);
171 pr_emerg("SR: %08lx SP: %08lx\n",
172 (long) fp
->estatus
, (long) fp
);
174 pr_emerg("r1: %08lx r2: %08lx r3: %08lx\n",
175 fp
->r1
, fp
->r2
, fp
->r3
);
177 pr_emerg("r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
178 fp
->r4
, fp
->r5
, fp
->r6
, fp
->r7
);
179 pr_emerg("r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
180 fp
->r8
, fp
->r9
, fp
->r10
, fp
->r11
);
181 pr_emerg("r12: %08lx r13: %08lx r14: %08lx r15: %08lx\n",
182 fp
->r12
, fp
->r13
, fp
->r14
, fp
->r15
);
183 pr_emerg("or2: %08lx ra: %08lx fp: %08lx sp: %08lx\n",
184 fp
->orig_r2
, fp
->ra
, fp
->fp
, fp
->sp
);
185 pr_emerg("\nUSP: %08x TRAPFRAME: %08x\n",
186 (unsigned int) fp
->sp
, (unsigned int) fp
);
189 tp
= ((unsigned char *) fp
->ea
) - 0x20;
190 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x40); i
+= 4) {
192 pr_emerg("\n%08x: ", (int) (tp
+ i
));
193 pr_emerg("%08x ", (int) *sp
++);
197 pr_emerg("\nKERNEL STACK:");
198 tp
= ((unsigned char *) fp
) - 0x40;
199 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0xc0); i
+= 4) {
201 pr_emerg("\n%08x: ", (int) (tp
+ i
));
202 pr_emerg("%08x ", (int) *sp
++);
207 pr_emerg("\nUSER STACK:");
208 tp
= (unsigned char *) (fp
->sp
- 0x10);
209 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x80); i
+= 4) {
211 pr_emerg("\n%08x: ", (int) (tp
+ i
));
212 pr_emerg("%08x ", (int) *sp
++);
217 unsigned long get_wchan(struct task_struct
*p
)
219 unsigned long fp
, pc
;
220 unsigned long stack_page
;
223 if (!p
|| p
== current
|| p
->state
== TASK_RUNNING
)
226 stack_page
= (unsigned long)p
;
227 fp
= ((struct switch_stack
*)p
->thread
.ksp
)->fp
; /* ;dgt2 */
229 if (fp
< stack_page
+sizeof(struct task_struct
) ||
230 fp
>= 8184+stack_page
) /* ;dgt2;tmp */
232 pc
= ((unsigned long *)fp
)[1];
233 if (!in_sched_functions(pc
))
235 fp
= *(unsigned long *) fp
;
236 } while (count
++ < 16); /* ;dgt2;tmp */
241 * Do necessary setup to start up a newly executed thread.
242 * Will startup in user mode (status_extension = 0).
244 void start_thread(struct pt_regs
*regs
, unsigned long pc
, unsigned long sp
)
246 memset((void *) regs
, 0, sizeof(struct pt_regs
));
247 regs
->estatus
= ESTATUS_EPIE
| ESTATUS_EU
;
252 #include <linux/elfcore.h>
254 /* Fill in the FPU structure for a core dump. */
255 int dump_fpu(struct pt_regs
*regs
, elf_fpregset_t
*r
)
257 return 0; /* Nios2 has no FPU and thus no FPU registers */