]>
Commit | Line | Data |
---|---|---|
e9564df7 GR |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. | |
3 | ||
4 | #include <linux/module.h> | |
5 | #include <linux/version.h> | |
6 | #include <linux/sched.h> | |
7 | #include <linux/sched/task_stack.h> | |
8 | #include <linux/sched/debug.h> | |
9 | #include <linux/delay.h> | |
10 | #include <linux/kallsyms.h> | |
11 | #include <linux/uaccess.h> | |
12 | #include <linux/ptrace.h> | |
13 | ||
14 | #include <asm/elf.h> | |
15 | #include <abi/reg_ops.h> | |
16 | ||
17 | struct cpuinfo_csky cpu_data[NR_CPUS]; | |
18 | ||
2f78c73f MH |
19 | #ifdef CONFIG_STACKPROTECTOR |
20 | #include <linux/stackprotector.h> | |
21 | unsigned long __stack_chk_guard __read_mostly; | |
22 | EXPORT_SYMBOL(__stack_chk_guard); | |
23 | #endif | |
24 | ||
e9564df7 GR |
25 | asmlinkage void ret_from_fork(void); |
26 | asmlinkage void ret_from_kernel_thread(void); | |
27 | ||
28 | /* | |
29 | * Some archs flush debug and FPU info here | |
30 | */ | |
31 | void flush_thread(void){} | |
32 | ||
714acdbd | 33 | int copy_thread(unsigned long clone_flags, |
e9564df7 GR |
34 | unsigned long usp, |
35 | unsigned long kthread_arg, | |
0b9f386c GR |
36 | struct task_struct *p, |
37 | unsigned long tls) | |
e9564df7 GR |
38 | { |
39 | struct switch_stack *childstack; | |
40 | struct pt_regs *childregs = task_pt_regs(p); | |
41 | ||
42 | #ifdef CONFIG_CPU_HAS_FPU | |
43 | save_to_user_fp(&p->thread.user_fp); | |
44 | #endif | |
45 | ||
46 | childstack = ((struct switch_stack *) childregs) - 1; | |
47 | memset(childstack, 0, sizeof(struct switch_stack)); | |
48 | ||
67002814 GR |
49 | /* setup thread.sp for switch_to !!! */ |
50 | p->thread.sp = (unsigned long)childstack; | |
e9564df7 GR |
51 | |
52 | if (unlikely(p->flags & PF_KTHREAD)) { | |
53 | memset(childregs, 0, sizeof(struct pt_regs)); | |
54 | childstack->r15 = (unsigned long) ret_from_kernel_thread; | |
48ede51f | 55 | childstack->r10 = kthread_arg; |
e9564df7 GR |
56 | childstack->r9 = usp; |
57 | childregs->sr = mfcr("psr"); | |
58 | } else { | |
59 | *childregs = *(current_pt_regs()); | |
60 | if (usp) | |
61 | childregs->usp = usp; | |
62 | if (clone_flags & CLONE_SETTLS) | |
63 | task_thread_info(p)->tp_value = childregs->tls | |
0b9f386c | 64 | = tls; |
e9564df7 GR |
65 | |
66 | childregs->a0 = 0; | |
67 | childstack->r15 = (unsigned long) ret_from_fork; | |
68 | } | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | /* Fill in the fpu structure for a core dump. */ | |
74 | int dump_fpu(struct pt_regs *regs, struct user_fp *fpu) | |
75 | { | |
76 | memcpy(fpu, ¤t->thread.user_fp, sizeof(*fpu)); | |
77 | return 1; | |
78 | } | |
79 | EXPORT_SYMBOL(dump_fpu); | |
80 | ||
81 | int dump_task_regs(struct task_struct *tsk, elf_gregset_t *pr_regs) | |
82 | { | |
83 | struct pt_regs *regs = task_pt_regs(tsk); | |
84 | ||
85 | /* NOTE: usp is error value. */ | |
86 | ELF_CORE_COPY_REGS((*pr_regs), regs) | |
87 | ||
88 | return 1; | |
89 | } | |
90 | ||
e9564df7 GR |
91 | #ifndef CONFIG_CPU_PM_NONE |
92 | void arch_cpu_idle(void) | |
93 | { | |
94 | #ifdef CONFIG_CPU_PM_WAIT | |
95 | asm volatile("wait\n"); | |
96 | #endif | |
97 | ||
98 | #ifdef CONFIG_CPU_PM_DOZE | |
99 | asm volatile("doze\n"); | |
100 | #endif | |
101 | ||
102 | #ifdef CONFIG_CPU_PM_STOP | |
103 | asm volatile("stop\n"); | |
104 | #endif | |
58c644ba | 105 | raw_local_irq_enable(); |
e9564df7 GR |
106 | } |
107 | #endif |