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/sched/task_stack.h>
20 #include <linux/mm_types.h>
21 #include <linux/tick.h>
22 #include <linux/uaccess.h>
24 #include <asm/unistd.h>
25 #include <asm/traps.h>
26 #include <asm/cpuinfo.h>
28 asmlinkage
void ret_from_fork(void);
29 asmlinkage
void ret_from_kernel_thread(void);
31 void (*pm_power_off
)(void) = NULL
;
32 EXPORT_SYMBOL(pm_power_off
);
34 void arch_cpu_idle(void)
40 * The development boards have no way to pull a board reset. Just jump to the
41 * cpu reset address and let the boot loader or the code in head.S take care of
42 * resetting peripherals.
44 void machine_restart(char *__unused
)
46 pr_notice("Machine restart (%08x)...\n", cpuinfo
.reset_addr
);
48 __asm__
__volatile__ (
51 : "r" (cpuinfo
.reset_addr
)
55 void machine_halt(void)
57 pr_notice("Machine halt...\n");
64 * There is no way to power off the development boards. So just spin for now. If
65 * we ever have a way of resetting a board using a GPIO we should add that here.
67 void machine_power_off(void)
69 pr_notice("Machine power off...\n");
75 void show_regs(struct pt_regs
*regs
)
78 show_regs_print_info(KERN_DEFAULT
);
80 pr_notice("r1: %08lx r2: %08lx r3: %08lx r4: %08lx\n",
81 regs
->r1
, regs
->r2
, regs
->r3
, regs
->r4
);
83 pr_notice("r5: %08lx r6: %08lx r7: %08lx r8: %08lx\n",
84 regs
->r5
, regs
->r6
, regs
->r7
, regs
->r8
);
86 pr_notice("r9: %08lx r10: %08lx r11: %08lx r12: %08lx\n",
87 regs
->r9
, regs
->r10
, regs
->r11
, regs
->r12
);
89 pr_notice("r13: %08lx r14: %08lx r15: %08lx\n",
90 regs
->r13
, regs
->r14
, regs
->r15
);
92 pr_notice("ra: %08lx fp: %08lx sp: %08lx gp: %08lx\n",
93 regs
->ra
, regs
->fp
, regs
->sp
, regs
->gp
);
95 pr_notice("ea: %08lx estatus: %08lx\n",
96 regs
->ea
, regs
->estatus
);
99 void flush_thread(void)
103 int copy_thread(unsigned long clone_flags
,
104 unsigned long usp
, unsigned long arg
, struct task_struct
*p
)
106 struct pt_regs
*childregs
= task_pt_regs(p
);
107 struct pt_regs
*regs
;
108 struct switch_stack
*stack
;
109 struct switch_stack
*childstack
=
110 ((struct switch_stack
*)childregs
) - 1;
112 if (unlikely(p
->flags
& PF_KTHREAD
)) {
113 memset(childstack
, 0,
114 sizeof(struct switch_stack
) + sizeof(struct pt_regs
));
116 childstack
->r16
= usp
; /* fn */
117 childstack
->r17
= arg
;
118 childstack
->ra
= (unsigned long) ret_from_kernel_thread
;
119 childregs
->estatus
= STATUS_PIE
;
120 childregs
->sp
= (unsigned long) childstack
;
122 p
->thread
.ksp
= (unsigned long) childstack
;
123 p
->thread
.kregs
= childregs
;
127 regs
= current_pt_regs();
129 childregs
->r2
= 0; /* Set the return value for the child. */
132 stack
= ((struct switch_stack
*) regs
) - 1;
133 *childstack
= *stack
;
134 childstack
->ra
= (unsigned long)ret_from_fork
;
135 p
->thread
.kregs
= childregs
;
136 p
->thread
.ksp
= (unsigned long) childstack
;
141 /* Initialize tls register. */
142 if (clone_flags
& CLONE_SETTLS
)
143 childstack
->r23
= regs
->r8
;
149 * Generic dumping code. Used for panic and debug.
151 void dump(struct pt_regs
*fp
)
157 pr_emerg("\nCURRENT PROCESS:\n\n");
158 pr_emerg("COMM=%s PID=%d\n", current
->comm
, current
->pid
);
161 pr_emerg("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
162 (int) current
->mm
->start_code
,
163 (int) current
->mm
->end_code
,
164 (int) current
->mm
->start_data
,
165 (int) current
->mm
->end_data
,
166 (int) current
->mm
->end_data
,
167 (int) current
->mm
->brk
);
168 pr_emerg("USER-STACK=%08x KERNEL-STACK=%08x\n\n",
169 (int) current
->mm
->start_stack
,
170 (int)(((unsigned long) current
) + THREAD_SIZE
));
173 pr_emerg("PC: %08lx\n", fp
->ea
);
174 pr_emerg("SR: %08lx SP: %08lx\n",
175 (long) fp
->estatus
, (long) fp
);
177 pr_emerg("r1: %08lx r2: %08lx r3: %08lx\n",
178 fp
->r1
, fp
->r2
, fp
->r3
);
180 pr_emerg("r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
181 fp
->r4
, fp
->r5
, fp
->r6
, fp
->r7
);
182 pr_emerg("r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
183 fp
->r8
, fp
->r9
, fp
->r10
, fp
->r11
);
184 pr_emerg("r12: %08lx r13: %08lx r14: %08lx r15: %08lx\n",
185 fp
->r12
, fp
->r13
, fp
->r14
, fp
->r15
);
186 pr_emerg("or2: %08lx ra: %08lx fp: %08lx sp: %08lx\n",
187 fp
->orig_r2
, fp
->ra
, fp
->fp
, fp
->sp
);
188 pr_emerg("\nUSP: %08x TRAPFRAME: %08x\n",
189 (unsigned int) fp
->sp
, (unsigned int) fp
);
192 tp
= ((unsigned char *) fp
->ea
) - 0x20;
193 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x40); i
+= 4) {
195 pr_emerg("\n%08x: ", (int) (tp
+ i
));
196 pr_emerg("%08x ", (int) *sp
++);
200 pr_emerg("\nKERNEL STACK:");
201 tp
= ((unsigned char *) fp
) - 0x40;
202 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0xc0); i
+= 4) {
204 pr_emerg("\n%08x: ", (int) (tp
+ i
));
205 pr_emerg("%08x ", (int) *sp
++);
210 pr_emerg("\nUSER STACK:");
211 tp
= (unsigned char *) (fp
->sp
- 0x10);
212 for (sp
= (unsigned long *) tp
, i
= 0; (i
< 0x80); i
+= 4) {
214 pr_emerg("\n%08x: ", (int) (tp
+ i
));
215 pr_emerg("%08x ", (int) *sp
++);
220 unsigned long get_wchan(struct task_struct
*p
)
222 unsigned long fp
, pc
;
223 unsigned long stack_page
;
226 if (!p
|| p
== current
|| p
->state
== TASK_RUNNING
)
229 stack_page
= (unsigned long)p
;
230 fp
= ((struct switch_stack
*)p
->thread
.ksp
)->fp
; /* ;dgt2 */
232 if (fp
< stack_page
+sizeof(struct task_struct
) ||
233 fp
>= 8184+stack_page
) /* ;dgt2;tmp */
235 pc
= ((unsigned long *)fp
)[1];
236 if (!in_sched_functions(pc
))
238 fp
= *(unsigned long *) fp
;
239 } while (count
++ < 16); /* ;dgt2;tmp */
244 * Do necessary setup to start up a newly executed thread.
245 * Will startup in user mode (status_extension = 0).
247 void start_thread(struct pt_regs
*regs
, unsigned long pc
, unsigned long sp
)
249 memset((void *) regs
, 0, sizeof(struct pt_regs
));
250 regs
->estatus
= ESTATUS_EPIE
| ESTATUS_EU
;
255 #include <linux/elfcore.h>
257 /* Fill in the FPU structure for a core dump. */
258 int dump_fpu(struct pt_regs
*regs
, elf_fpregset_t
*r
)
260 return 0; /* Nios2 has no FPU and thus no FPU registers */