root/arch/h8300/kernel/process.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arch_cpu_idle
  2. machine_restart
  3. machine_halt
  4. machine_power_off
  5. show_regs
  6. flush_thread
  7. copy_thread
  8. get_wchan
  9. sys_clone

   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 
  50 void (*pm_power_off)(void) = NULL;
  51 EXPORT_SYMBOL(pm_power_off);
  52 
  53 asmlinkage void ret_from_fork(void);
  54 asmlinkage void ret_from_kernel_thread(void);
  55 
  56 /*
  57  * The idle loop on an H8/300..
  58  */
  59 void arch_cpu_idle(void)
  60 {
  61         local_irq_enable();
  62         __asm__("sleep");
  63 }
  64 
  65 void machine_restart(char *__unused)
  66 {
  67         local_irq_disable();
  68         __asm__("jmp @@0");
  69 }
  70 
  71 void machine_halt(void)
  72 {
  73         local_irq_disable();
  74         __asm__("sleep");
  75         for (;;)
  76                 ;
  77 }
  78 
  79 void machine_power_off(void)
  80 {
  81         local_irq_disable();
  82         __asm__("sleep");
  83         for (;;)
  84                 ;
  85 }
  86 
  87 void 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 
 105 void flush_thread(void)
 106 {
 107 }
 108 
 109 int 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 
 133 unsigned 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 */
 157 asmlinkage 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 }

/* [<][>][^][v][top][bottom][index][help] */