Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  linux/arch/h8300/kernel/process.c
  4 *
  5 * Yoshinori Sato <ysato@users.sourceforge.jp>
  6 *
  7 *  Based on:
  8 *
  9 *  linux/arch/m68knommu/kernel/process.c
 10 *
 11 *  Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
 12 *                      Kenneth Albanowski <kjahds@kjahds.com>,
 13 *                      The Silver Hammer Group, Ltd.
 14 *
 15 *  linux/arch/m68k/kernel/process.c
 16 *
 17 *  Copyright (C) 1995  Hamish Macdonald
 18 *
 19 *  68060 fixes by Jesper Skov
 20 */
 21
 22/*
 23 * This file handles the architecture-dependent parts of process handling..
 24 */
 25
 26#include <linux/errno.h>
 27#include <linux/module.h>
 28#include <linux/sched.h>
 29#include <linux/sched/debug.h>
 30#include <linux/sched/task.h>
 31#include <linux/sched/task_stack.h>
 32#include <linux/kernel.h>
 33#include <linux/mm.h>
 34#include <linux/smp.h>
 35#include <linux/stddef.h>
 36#include <linux/unistd.h>
 37#include <linux/ptrace.h>
 38#include <linux/user.h>
 39#include <linux/interrupt.h>
 40#include <linux/reboot.h>
 41#include <linux/fs.h>
 42#include <linux/slab.h>
 43#include <linux/rcupdate.h>
 44
 45#include <linux/uaccess.h>
 46#include <asm/traps.h>
 47#include <asm/setup.h>
 48#include <asm/pgtable.h>
 49
 50void (*pm_power_off)(void) = NULL;
 51EXPORT_SYMBOL(pm_power_off);
 52
 53asmlinkage void ret_from_fork(void);
 54asmlinkage void ret_from_kernel_thread(void);
 55
 56/*
 57 * The idle loop on an H8/300..
 58 */
 59void arch_cpu_idle(void)
 60{
 61	local_irq_enable();
 62	__asm__("sleep");
 63}
 64
 65void machine_restart(char *__unused)
 66{
 67	local_irq_disable();
 68	__asm__("jmp @@0");
 69}
 70
 71void machine_halt(void)
 72{
 73	local_irq_disable();
 74	__asm__("sleep");
 75	for (;;)
 76		;
 77}
 78
 79void machine_power_off(void)
 80{
 81	local_irq_disable();
 82	__asm__("sleep");
 83	for (;;)
 84		;
 85}
 86
 87void show_regs(struct pt_regs *regs)
 88{
 89	show_regs_print_info(KERN_DEFAULT);
 90
 91	pr_notice("\n");
 92	pr_notice("PC: %08lx  Status: %02x\n",
 93	       regs->pc, regs->ccr);
 94	pr_notice("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n",
 95	       regs->orig_er0, regs->er0, regs->er1);
 96	pr_notice("ER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx\n",
 97	       regs->er2, regs->er3, regs->er4, regs->er5);
 98	pr_notice("ER6' %08lx ", regs->er6);
 99	if (user_mode(regs))
100		printk("USP: %08lx\n", rdusp());
101	else
102		printk("\n");
103}
104
105void flush_thread(void)
106{
107}
108
109int copy_thread(unsigned long clone_flags,
110		unsigned long usp, unsigned long topstk,
111		struct task_struct *p)
112{
113	struct pt_regs *childregs;
114
115	childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
116
117	if (unlikely(p->flags & PF_KTHREAD)) {
118		memset(childregs, 0, sizeof(struct pt_regs));
119		childregs->retpc = (unsigned long) ret_from_kernel_thread;
120		childregs->er4 = topstk; /* arg */
121		childregs->er5 = usp; /* fn */
122	}  else {
123		*childregs = *current_pt_regs();
124		childregs->er0 = 0;
125		childregs->retpc = (unsigned long) ret_from_fork;
126		p->thread.usp = usp ?: rdusp();
127	}
128	p->thread.ksp = (unsigned long)childregs;
129
130	return 0;
131}
132
133unsigned long get_wchan(struct task_struct *p)
134{
135	unsigned long fp, pc;
136	unsigned long stack_page;
137	int count = 0;
138
139	if (!p || p == current || p->state == TASK_RUNNING)
140		return 0;
141
142	stack_page = (unsigned long)p;
143	fp = ((struct pt_regs *)p->thread.ksp)->er6;
144	do {
145		if (fp < stack_page+sizeof(struct thread_info) ||
146		    fp >= 8184+stack_page)
147			return 0;
148		pc = ((unsigned long *)fp)[1];
149		if (!in_sched_functions(pc))
150			return pc;
151		fp = *(unsigned long *) fp;
152	} while (count++ < 16);
153	return 0;
154}
155
156/* generic sys_clone is not enough registers */
157asmlinkage int sys_clone(unsigned long __user *args)
158{
159	unsigned long clone_flags;
160	unsigned long  newsp;
161	uintptr_t parent_tidptr;
162	uintptr_t child_tidptr;
163
164	get_user(clone_flags, &args[0]);
165	get_user(newsp, &args[1]);
166	get_user(parent_tidptr, &args[2]);
167	get_user(child_tidptr, &args[3]);
168	return do_fork(clone_flags, newsp, 0,
169		       (int __user *)parent_tidptr, (int __user *)child_tidptr);
170}