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)
99 int copy_thread(unsigned long clone_flags
,
100 unsigned long usp
, unsigned long arg
, struct task_struct
*p
)
102 struct pt_regs
*childregs
= task_pt_regs(p
);
103 struct pt_regs
*regs
;
104 struct switch_stack
*stack
;
105 struct switch_stack
*childstack
=
106 ((struct switch_stack
*)childregs
) - 1;
108 if (unlikely(p
->flags
& PF_KTHREAD
)) {
109 memset(childstack
, 0,
110 sizeof(struct switch_stack
) + sizeof(struct pt_regs
));
112 childstack
->r16
= usp
; /* fn */
113 childstack
->r17
= arg
;
114 childstack
->ra
= (unsigned long) ret_from_kernel_thread
;
115 childregs
->estatus
= STATUS_PIE
;
116 childregs
->sp
= (unsigned long) childstack
;
118 p
->thread
.ksp
= (unsigned long) childstack
;
119 p
->thread
.kregs
= childregs
;
123 regs
= current_pt_regs();
125 childregs
->r2
= 0; /* Set the return value for the child. */
128 stack
= ((struct switch_stack
*) regs
) - 1;
129 *childstack
= *stack
;
130 childstack
->ra
= (unsigned long)ret_from_fork
;
131 p
->thread
.kregs
= childregs
;
132 p
->thread
.ksp
= (unsigned long) childstack
;
137 /* Initialize tls register. */
138 if (clone_flags
& CLONE_SETTLS
)
139 childstack
->r23
= regs
->r8
;
145 * Generic dumping code. Used for panic and debug.
147 void dump(struct pt_regs
*fp
)
153 pr_emerg("\nCURRENT PROCESS:\n\n");
154 pr_emerg("COMM=%s PID=%d\n", current
->comm
, current
->pid
);
157 pr_emerg("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
158 (int) current
->mm
->start_code
,
159 (int) current
->mm
->end_code
,
160 (int) current
->mm
->start_data
,
161 (int) current
->mm
->end_data
,
162 (int) current
->mm
->end_data
,
163 (int) current
->mm
->brk
);
164 pr_emerg("USER-STACK=%08x KERNEL-STACK=%08x\n\n",
165 (int) current
->mm
->start_stack
,
166 (int)(((unsigned long) current
) + THREAD_SIZE
));
169 pr_emerg("PC: %08lx\n", fp
->ea
);
170 pr_emerg("SR: %08lx SP: %08lx\n",
171 (long) fp
->estatus
, (long) fp
);
173 pr_emerg("r1: %08lx r2: %08lx r3: %08lx\n",
174 fp
->r1
, fp
->r2
, fp
->r3
);
176 pr_emerg("r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
177 fp
->r4
, fp
->r5
, fp
->r6
, fp
->r7
);
178 pr_emerg("r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
179 fp
->r8
, fp
->r9
, fp
->r10
, fp
->r11
);
180 pr_emerg("r12: %08lx r13: %08lx r14: %08lx r15: %08lx\n",
181 fp
->r12
, fp
->r13
, fp
->r14
, fp
->r15
);
182 pr_emerg("or2: %08lx ra: %08lx fp: %08lx sp: %08lx\n",
183 fp
->orig_r2
, fp
->ra
, fp
->fp
, fp
->sp
);
184 pr_emerg("\nUSP: %08x TRAPFRAME: %08x\n",
185 (unsigned int) fp
->sp
, (unsigned int) fp
);
188 tp
= ((unsigned char *) fp
->ea
) - 0x20;
189 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x40); i
+= 4) {
191 pr_emerg("\n%08x: ", (int) (tp
+ i
));
192 pr_emerg("%08x ", (int) *sp
++);
196 pr_emerg("\nKERNEL STACK:");
197 tp
= ((unsigned char *) fp
) - 0x40;
198 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0xc0); i
+= 4) {
200 pr_emerg("\n%08x: ", (int) (tp
+ i
));
201 pr_emerg("%08x ", (int) *sp
++);
206 pr_emerg("\nUSER STACK:");
207 tp
= (unsigned char *) (fp
->sp
- 0x10);
208 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x80); i
+= 4) {
210 pr_emerg("\n%08x: ", (int) (tp
+ i
));
211 pr_emerg("%08x ", (int) *sp
++);
216 unsigned long get_wchan(struct task_struct
*p
)
218 unsigned long fp
, pc
;
219 unsigned long stack_page
;
222 if (!p
|| p
== current
|| p
->state
== TASK_RUNNING
)
225 stack_page
= (unsigned long)p
;
226 fp
= ((struct switch_stack
*)p
->thread
.ksp
)->fp
; /* ;dgt2 */
228 if (fp
< stack_page
+sizeof(struct task_struct
) ||
229 fp
>= 8184+stack_page
) /* ;dgt2;tmp */
231 pc
= ((unsigned long *)fp
)[1];
232 if (!in_sched_functions(pc
))
234 fp
= *(unsigned long *) fp
;
235 } while (count
++ < 16); /* ;dgt2;tmp */
240 * Do necessary setup to start up a newly executed thread.
241 * Will startup in user mode (status_extension = 0).
243 void start_thread(struct pt_regs
*regs
, unsigned long pc
, unsigned long sp
)
245 memset((void *) regs
, 0, sizeof(struct pt_regs
));
246 regs
->estatus
= ESTATUS_EPIE
| ESTATUS_EU
;
251 #include <linux/elfcore.h>
253 /* Fill in the FPU structure for a core dump. */
254 int dump_fpu(struct pt_regs
*regs
, elf_fpregset_t
*r
)
256 return 0; /* Nios2 has no FPU and thus no FPU registers */