| Mikael Starvik | 5d01e6c | 2005-07-27 11:44:43 -0700 | [diff] [blame] | 1 | /* $Id: process.c,v 1.21 2005/03/04 08:16:17 starvik Exp $ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 |  *  | 
 | 3 |  *  linux/arch/cris/kernel/process.c | 
 | 4 |  * | 
 | 5 |  *  Copyright (C) 1995  Linus Torvalds | 
 | 6 |  *  Copyright (C) 2000-2002  Axis Communications AB | 
 | 7 |  * | 
 | 8 |  *  Authors:   Bjorn Wesen (bjornw@axis.com) | 
 | 9 |  * | 
 | 10 |  *  $Log: process.c,v $ | 
| Mikael Starvik | 5d01e6c | 2005-07-27 11:44:43 -0700 | [diff] [blame] | 11 |  *  Revision 1.21  2005/03/04 08:16:17  starvik | 
 | 12 |  *  Merge of Linux 2.6.11. | 
 | 13 |  * | 
 | 14 |  *  Revision 1.20  2005/01/18 05:57:22  starvik | 
 | 15 |  *  Renamed hlt_counter to cris_hlt_counter and made it global. | 
 | 16 |  * | 
 | 17 |  *  Revision 1.19  2004/10/19 13:07:43  starvik | 
 | 18 |  *  Merge of Linux 2.6.9 | 
 | 19 |  * | 
 | 20 |  *  Revision 1.18  2004/08/16 12:37:23  starvik | 
 | 21 |  *  Merge of Linux 2.6.8 | 
 | 22 |  * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 |  *  Revision 1.17  2004/04/05 13:53:48  starvik | 
 | 24 |  *  Merge of Linux 2.6.5 | 
 | 25 |  * | 
 | 26 |  *  Revision 1.16  2003/10/27 08:04:33  starvik | 
 | 27 |  *  Merge of Linux 2.6.0-test9 | 
 | 28 |  * | 
 | 29 |  *  Revision 1.15  2003/09/11 07:29:52  starvik | 
 | 30 |  *  Merge of Linux 2.6.0-test5 | 
 | 31 |  * | 
 | 32 |  *  Revision 1.14  2003/06/10 10:21:12  johana | 
 | 33 |  *  Moved thread_saved_pc() from arch/cris/kernel/process.c to | 
 | 34 |  *  subarch specific process.c. arch-v32 has an erp, no irp. | 
 | 35 |  * | 
 | 36 |  *  Revision 1.13  2003/04/09 05:20:47  starvik | 
 | 37 |  *  Merge of Linux 2.5.67 | 
 | 38 |  * | 
 | 39 |  *  Revision 1.12  2002/12/11 15:41:11  starvik | 
 | 40 |  *  Extracted v10 (ETRAX 100LX) specific stuff to arch/cris/arch-v10/kernel | 
 | 41 |  * | 
 | 42 |  *  Revision 1.11  2002/12/10 09:00:10  starvik | 
 | 43 |  *  Merge of Linux 2.5.51 | 
 | 44 |  * | 
 | 45 |  *  Revision 1.10  2002/11/27 08:42:34  starvik | 
 | 46 |  *  Argument to user_regs() is thread_info* | 
 | 47 |  * | 
 | 48 |  *  Revision 1.9  2002/11/26 09:44:21  starvik | 
 | 49 |  *  New threads exits through ret_from_fork (necessary for preemptive scheduling) | 
 | 50 |  * | 
 | 51 |  *  Revision 1.8  2002/11/19 14:35:24  starvik | 
 | 52 |  *  Changes from linux 2.4 | 
 | 53 |  *  Changed struct initializer syntax to the currently prefered notation | 
 | 54 |  * | 
 | 55 |  *  Revision 1.7  2002/11/18 07:39:42  starvik | 
 | 56 |  *  thread_saved_pc moved here from processor.h | 
 | 57 |  * | 
 | 58 |  *  Revision 1.6  2002/11/14 06:51:27  starvik | 
 | 59 |  *  Made cpu_idle more similar with other archs | 
 | 60 |  *  init_task_union -> init_thread_union | 
 | 61 |  *  Updated for new interrupt macros | 
 | 62 |  *  sys_clone and do_fork have a new argument, user_tid | 
 | 63 |  * | 
 | 64 |  *  Revision 1.5  2002/11/05 06:45:11  starvik | 
 | 65 |  *  Merge of Linux 2.5.45 | 
 | 66 |  * | 
 | 67 |  *  Revision 1.4  2002/02/05 15:37:44  bjornw | 
 | 68 |  *  Need init_task.h | 
 | 69 |  * | 
 | 70 |  *  Revision 1.3  2002/01/21 15:22:49  bjornw | 
 | 71 |  *  current->counter is gone | 
 | 72 |  * | 
 | 73 |  *  Revision 1.22  2001/11/13 09:40:43  orjanf | 
 | 74 |  *  Added dump_fpu (needed for core dumps). | 
 | 75 |  * | 
 | 76 |  *  Revision 1.21  2001/11/12 18:26:21  pkj | 
 | 77 |  *  Fixed compiler warnings. | 
 | 78 |  * | 
 | 79 |  *  Revision 1.20  2001/10/03 08:21:39  jonashg | 
 | 80 |  *  cause_of_death does not exist if CONFIG_SVINTO_SIM is defined. | 
 | 81 |  * | 
 | 82 |  *  Revision 1.19  2001/09/26 11:52:54  bjornw | 
 | 83 |  *  INIT_MMAP is gone in 2.4.10 | 
 | 84 |  * | 
 | 85 |  *  Revision 1.18  2001/08/21 21:43:51  hp | 
 | 86 |  *  Move last watchdog fix inside #ifdef CONFIG_ETRAX_WATCHDOG | 
 | 87 |  * | 
 | 88 |  *  Revision 1.17  2001/08/21 13:48:01  jonashg | 
 | 89 |  *  Added fix by HP to avoid oops when doing a hard_reset_now. | 
 | 90 |  * | 
 | 91 |  *  Revision 1.16  2001/06/21 02:00:40  hp | 
 | 92 |  *  	* entry.S: Include asm/unistd.h. | 
 | 93 |  *  	(_sys_call_table): Use section .rodata, not .data. | 
 | 94 |  *  	(_kernel_thread): Move from... | 
 | 95 |  *  	* process.c: ... here. | 
 | 96 |  *  	* entryoffsets.c (VAL): Break out from... | 
 | 97 |  *  	(OF): Use VAL. | 
 | 98 |  *  	(LCLONE_VM): New asmified value from CLONE_VM. | 
 | 99 |  * | 
 | 100 |  *  Revision 1.15  2001/06/20 16:31:57  hp | 
 | 101 |  *  Add comments to describe empty functions according to review. | 
 | 102 |  * | 
 | 103 |  *  Revision 1.14  2001/05/29 11:27:59  markusl | 
 | 104 |  *  Fixed so that hard_reset_now will do reset even if watchdog wasn't enabled | 
 | 105 |  * | 
 | 106 |  *  Revision 1.13  2001/03/20 19:44:06  bjornw | 
 | 107 |  *  Use the 7th syscall argument for regs instead of current_regs | 
 | 108 |  * | 
 | 109 |  */ | 
 | 110 |  | 
 | 111 | /* | 
 | 112 |  * This file handles the architecture-dependent parts of process handling.. | 
 | 113 |  */ | 
 | 114 |  | 
 | 115 | #include <asm/atomic.h> | 
 | 116 | #include <asm/pgtable.h> | 
 | 117 | #include <asm/uaccess.h> | 
 | 118 | #include <asm/irq.h> | 
 | 119 | #include <linux/module.h> | 
 | 120 | #include <linux/spinlock.h> | 
 | 121 | #include <linux/fs_struct.h> | 
 | 122 | #include <linux/init_task.h> | 
 | 123 | #include <linux/sched.h> | 
 | 124 | #include <linux/fs.h> | 
 | 125 | #include <linux/user.h> | 
 | 126 | #include <linux/elfcore.h> | 
 | 127 | #include <linux/mqueue.h> | 
| Eric W. Biederman | 16dcb4b | 2005-07-26 11:32:34 -0600 | [diff] [blame] | 128 | #include <linux/reboot.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 129 |  | 
 | 130 | //#define DEBUG | 
 | 131 |  | 
 | 132 | /* | 
 | 133 |  * Initial task structure. Make this a per-architecture thing, | 
 | 134 |  * because different architectures tend to have different | 
 | 135 |  * alignment requirements and potentially different initial | 
 | 136 |  * setup. | 
 | 137 |  */ | 
 | 138 |  | 
 | 139 | static struct fs_struct init_fs = INIT_FS; | 
 | 140 | static struct files_struct init_files = INIT_FILES; | 
 | 141 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 
 | 142 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 
 | 143 | struct mm_struct init_mm = INIT_MM(init_mm); | 
 | 144 |  | 
 | 145 | EXPORT_SYMBOL(init_mm); | 
 | 146 |  | 
 | 147 | /* | 
 | 148 |  * Initial thread structure. | 
 | 149 |  * | 
 | 150 |  * We need to make sure that this is 8192-byte aligned due to the | 
 | 151 |  * way process stacks are handled. This is done by having a special | 
 | 152 |  * "init_task" linker map entry.. | 
 | 153 |  */ | 
 | 154 | union thread_union init_thread_union  | 
 | 155 | 	__attribute__((__section__(".data.init_task"))) = | 
 | 156 | 		{ INIT_THREAD_INFO(init_task) }; | 
 | 157 |  | 
 | 158 | /* | 
 | 159 |  * Initial task structure. | 
 | 160 |  * | 
 | 161 |  * All other task structs will be allocated on slabs in fork.c | 
 | 162 |  */ | 
 | 163 | struct task_struct init_task = INIT_TASK(init_task); | 
 | 164 |  | 
 | 165 | EXPORT_SYMBOL(init_task); | 
 | 166 |  | 
 | 167 | /* | 
 | 168 |  * The hlt_counter, disable_hlt and enable_hlt is just here as a hook if | 
 | 169 |  * there would ever be a halt sequence (for power save when idle) with | 
 | 170 |  * some largish delay when halting or resuming *and* a driver that can't | 
 | 171 |  * afford that delay.  The hlt_counter would then be checked before | 
 | 172 |  * executing the halt sequence, and the driver marks the unhaltable | 
 | 173 |  * region by enable_hlt/disable_hlt. | 
 | 174 |  */ | 
 | 175 |  | 
| Mikael Starvik | 5d01e6c | 2005-07-27 11:44:43 -0700 | [diff] [blame] | 176 | int cris_hlt_counter=0; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 177 |  | 
 | 178 | void disable_hlt(void) | 
 | 179 | { | 
| Mikael Starvik | 5d01e6c | 2005-07-27 11:44:43 -0700 | [diff] [blame] | 180 | 	cris_hlt_counter++; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 181 | } | 
 | 182 |  | 
 | 183 | EXPORT_SYMBOL(disable_hlt); | 
 | 184 |  | 
 | 185 | void enable_hlt(void) | 
 | 186 | { | 
| Mikael Starvik | 5d01e6c | 2005-07-27 11:44:43 -0700 | [diff] [blame] | 187 | 	cris_hlt_counter--; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 | } | 
 | 189 |  | 
 | 190 | EXPORT_SYMBOL(enable_hlt); | 
 | 191 |   | 
 | 192 | /* | 
 | 193 |  * The following aren't currently used. | 
 | 194 |  */ | 
 | 195 | void (*pm_idle)(void); | 
 | 196 |  | 
 | 197 | extern void default_idle(void); | 
 | 198 |  | 
 | 199 | /* | 
 | 200 |  * The idle thread. There's no useful work to be | 
 | 201 |  * done, so just try to conserve power and have a | 
 | 202 |  * low exit latency (ie sit in a loop waiting for | 
 | 203 |  * somebody to say that they'd like to reschedule) | 
 | 204 |  */ | 
 | 205 | void cpu_idle (void) | 
 | 206 | { | 
 | 207 | 	/* endless idle loop with no priority at all */ | 
 | 208 | 	while (1) { | 
 | 209 | 		while (!need_resched()) { | 
| Mikael Starvik | 5d01e6c | 2005-07-27 11:44:43 -0700 | [diff] [blame] | 210 | 			void (*idle)(void); | 
 | 211 | 			/* | 
 | 212 | 			 * Mark this as an RCU critical section so that | 
 | 213 | 			 * synchronize_kernel() in the unload path waits | 
 | 214 | 			 * for our completion. | 
 | 215 | 			 */ | 
 | 216 | 			idle = pm_idle; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 217 | 			if (!idle) | 
 | 218 | 				idle = default_idle; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 219 | 			idle(); | 
 | 220 | 		} | 
 | 221 | 		schedule(); | 
 | 222 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 223 | } | 
 | 224 |  | 
 | 225 | void hard_reset_now (void); | 
 | 226 |  | 
| Eric W. Biederman | 16dcb4b | 2005-07-26 11:32:34 -0600 | [diff] [blame] | 227 | void machine_restart(char *cmd) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 228 | { | 
 | 229 | 	hard_reset_now(); | 
 | 230 | } | 
 | 231 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 232 | /* | 
 | 233 |  * Similar to machine_power_off, but don't shut off power.  Add code | 
 | 234 |  * here to freeze the system for e.g. post-mortem debug purpose when | 
 | 235 |  * possible.  This halt has nothing to do with the idle halt. | 
 | 236 |  */ | 
 | 237 |  | 
 | 238 | void machine_halt(void) | 
 | 239 | { | 
 | 240 | } | 
 | 241 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 242 | /* If or when software power-off is implemented, add code here.  */ | 
 | 243 |  | 
 | 244 | void machine_power_off(void) | 
 | 245 | { | 
 | 246 | } | 
 | 247 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 248 | /* | 
 | 249 |  * When a process does an "exec", machine state like FPU and debug | 
 | 250 |  * registers need to be reset.  This is a hook function for that. | 
 | 251 |  * Currently we don't have any such state to reset, so this is empty. | 
 | 252 |  */ | 
 | 253 |  | 
 | 254 | void flush_thread(void) | 
 | 255 | { | 
 | 256 | } | 
 | 257 |  | 
 | 258 | /* | 
 | 259 |  * fill in the user structure for a core dump.. | 
 | 260 |  */ | 
 | 261 | void dump_thread(struct pt_regs * regs, struct user * dump) | 
 | 262 | { | 
 | 263 | #if 0 | 
 | 264 | 	int i; | 
 | 265 |  | 
 | 266 | 	/* changed the size calculations - should hopefully work better. lbt */ | 
 | 267 | 	dump->magic = CMAGIC; | 
 | 268 | 	dump->start_code = 0; | 
 | 269 | 	dump->start_stack = regs->esp & ~(PAGE_SIZE - 1); | 
 | 270 | 	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; | 
 | 271 | 	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; | 
 | 272 | 	dump->u_dsize -= dump->u_tsize; | 
 | 273 | 	dump->u_ssize = 0; | 
 | 274 | 	for (i = 0; i < 8; i++) | 
 | 275 | 		dump->u_debugreg[i] = current->debugreg[i];   | 
 | 276 |  | 
 | 277 | 	if (dump->start_stack < TASK_SIZE) | 
 | 278 | 		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; | 
 | 279 |  | 
 | 280 | 	dump->regs = *regs; | 
 | 281 |  | 
 | 282 | 	dump->u_fpvalid = dump_fpu (regs, &dump->i387); | 
 | 283 | #endif  | 
 | 284 | } | 
 | 285 |  | 
 | 286 | /* Fill in the fpu structure for a core dump. */ | 
 | 287 | int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) | 
 | 288 | { | 
 | 289 |         return 0; | 
 | 290 | } |