^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * OpenRISC process.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Linux architectural port borrowing liberally from similar works of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * others. All original copyrights apply as per the original source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * declaration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Modifications for the OpenRISC architecture:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This file handles the architecture-dependent parts of process handling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define __KERNEL_SYSCALLS__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/sched/task.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/elfcore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/init_task.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/mqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/spr_defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Pointer to Current thread info structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Used at user space -> kernel transitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct thread_info *current_thread_info_set[NR_CPUS] = { &init_thread_info, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void machine_restart(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) printk(KERN_INFO "*** MACHINE RESTART ***\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __asm__("l.nop 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Similar to machine_power_off, but don't shut off power. Add code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * here to freeze the system for e.g. post-mortem debug purpose when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * possible. This halt has nothing to do with the idle halt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void machine_halt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) printk(KERN_INFO "*** MACHINE HALT ***\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __asm__("l.nop 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* If or when software power-off is implemented, add code here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) void machine_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) __asm__("l.nop 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Send the doze signal to the cpu if available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Make sure, that all interrupts are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void arch_cpu_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) raw_local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (mfspr(SPR_UPR) & SPR_UPR_PMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mtspr(SPR_PMR, mfspr(SPR_PMR) | SPR_PMR_DME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void (*pm_power_off) (void) = machine_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) EXPORT_SYMBOL(pm_power_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * When a process does an "exec", machine state like FPU and debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * registers need to be reset. This is a hook function for that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Currently we don't have any such state to reset, so this is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void flush_thread(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void show_regs(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) extern void show_registers(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) show_regs_print_info(KERN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* __PHX__ cleanup this mess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) show_registers(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void release_thread(struct task_struct *dead_task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * Copy the thread-specific (arch specific) info from the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * process to the new one p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) extern asmlinkage void ret_from_fork(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * copy_thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @clone_flags: flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @usp: user stack pointer or fn for kernel thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @arg: arg to fn for kernel thread; always NULL for userspace thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @p: the newly created task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @tls: the Thread Local Storage pointer for the new process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * At the top of a newly initialized kernel stack are two stacked pt_reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * structures. The first (topmost) is the userspace context of the thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * The second is the kernelspace context of the thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * A kernel thread will not be returning to userspace, so the topmost pt_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * struct can be uninitialized; it _does_ need to exist, though, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * a kernel thread can become a userspace thread by doing a kernel_execve, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * which case the topmost context will be initialized and used for 'returning'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * The second pt_reg struct needs to be initialized to 'return' to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * ret_from_fork. A kernel thread will need to set r20 to the address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * a function to call into (with arg in r22); userspace threads need to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * r20 to NULL in which case ret_from_fork will just continue a return to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * A kernel thread 'fn' may return; this is effectively what happens when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * kernel_execve is called. In that case, the userspace pt_regs must have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * been initialized (which kernel_execve takes care of, see start_thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * below); ret_from_fork will then continue its execution causing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * 'kernel thread' to return to userspace as a userspace thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct task_struct *p, unsigned long tls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct pt_regs *userregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct pt_regs *kregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned long top_of_kernel_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) top_of_kernel_stack = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Locate userspace context on stack... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) sp -= STACK_FRAME_OVERHEAD; /* redzone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) sp -= sizeof(struct pt_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) userregs = (struct pt_regs *) sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* ...and kernel context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) sp -= STACK_FRAME_OVERHEAD; /* redzone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) sp -= sizeof(struct pt_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) kregs = (struct pt_regs *)sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (unlikely(p->flags & PF_KTHREAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) memset(kregs, 0, sizeof(struct pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) kregs->gpr[20] = usp; /* fn, kernel thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kregs->gpr[22] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *userregs = *current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (usp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) userregs->sp = usp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * For CLONE_SETTLS set "tp" (r10) to the TLS pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (clone_flags & CLONE_SETTLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) userregs->gpr[10] = tls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) userregs->gpr[11] = 0; /* Result from fork() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) kregs->gpr[20] = 0; /* Userspace thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * _switch wants the kernel stack page in pt_regs->sp so that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * can restore it to thread_info->ksp... see _switch for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) kregs->sp = top_of_kernel_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) kregs->gpr[9] = (unsigned long)ret_from_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) task_thread_info(p)->ksp = (unsigned long)kregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Set up a thread for executing a new program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned long sr = mfspr(SPR_SR) & ~SPR_SR_SM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) memset(regs, 0, sizeof(struct pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) regs->pc = pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) regs->sr = sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) regs->sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) extern struct thread_info *_switch(struct thread_info *old_ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct thread_info *new_ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) extern int lwa_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct task_struct *__switch_to(struct task_struct *old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct task_struct *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct task_struct *last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct thread_info *new_ti, *old_ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* current_set is an array of saved current pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * (one for each cpu). we need them at user->kernel transition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * while we save them at kernel->user transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) new_ti = new->stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) old_ti = old->stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) lwa_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) current_thread_info_set[smp_processor_id()] = new_ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) last = (_switch(old_ti, new_ti))->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Write out registers in core dump format, as defined by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * struct user_regs_struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) void dump_elf_thread(elf_greg_t *dest, struct pt_regs* regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dest[0] = 0; /* r0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) memcpy(dest+1, regs->gpr+1, 31*sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) dest[32] = regs->pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dest[33] = regs->sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) dest[34] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dest[35] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned long get_wchan(struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }