Import 2.3.13pre1
[davej-history.git] / arch / alpha / kernel / process.c
blobcd763398e22932109706b2ecc6e9356c7eaf22c1
1 /*
2 * linux/arch/alpha/kernel/process.c
4 * Copyright (C) 1995 Linus Torvalds
5 */
7 /*
8 * This file handles the architecture-dependent parts of process handling.
9 */
11 #include <linux/config.h>
12 #include <linux/errno.h>
13 #include <linux/sched.h>
14 #include <linux/kernel.h>
15 #include <linux/mm.h>
16 #include <linux/smp.h>
17 #include <linux/smp_lock.h>
18 #include <linux/stddef.h>
19 #include <linux/unistd.h>
20 #include <linux/ptrace.h>
21 #include <linux/malloc.h>
22 #include <linux/user.h>
23 #include <linux/a.out.h>
24 #include <linux/utsname.h>
25 #include <linux/time.h>
26 #include <linux/major.h>
27 #include <linux/stat.h>
28 #include <linux/mman.h>
29 #include <linux/elfcore.h>
30 #include <linux/reboot.h>
31 #include <linux/console.h>
33 #ifdef CONFIG_RTC
34 #include <linux/mc146818rtc.h>
35 #endif
37 #include <asm/reg.h>
38 #include <asm/uaccess.h>
39 #include <asm/system.h>
40 #include <asm/io.h>
41 #include <asm/pgtable.h>
42 #include <asm/hwrpb.h>
43 #include <asm/fpu.h>
45 #include "proto.h"
46 #include "bios32.h"
49 * Initial task structure. Make this a per-architecture thing,
50 * because different architectures tend to have different
51 * alignment requirements and potentially different initial
52 * setup.
55 unsigned long init_user_stack[1024] = { STACK_MAGIC, };
56 static struct vm_area_struct init_mmap = INIT_MMAP;
57 static struct fs_struct init_fs = INIT_FS;
58 static struct files_struct init_files = INIT_FILES;
59 static struct signal_struct init_signals = INIT_SIGNALS;
60 struct mm_struct init_mm = INIT_MM(init_mm);
62 union task_union init_task_union __attribute__((section("init_task")))
63 = { task: INIT_TASK(init_task_union.task) };
66 * No need to acquire the kernel lock, we're entirely local..
68 asmlinkage int
69 sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
70 unsigned long a3, unsigned long a4, unsigned long a5,
71 struct pt_regs regs)
73 (&regs)->hae = hae;
74 return 0;
77 #ifdef __SMP__
78 int
79 cpu_idle(void *unused)
81 /* An endless idle loop with no priority at all. */
82 current->priority = 0;
83 current->counter = -100;
85 while (1) {
86 /* FIXME -- EV6 and LCA45 know how to power down
87 the CPU. */
89 /* Although we are an idle CPU, we do not want to
90 get into the scheduler unnecessarily. */
91 if (current->need_resched) {
92 schedule();
93 check_pgt_cache();
97 #endif
99 asmlinkage int
100 sys_idle(void)
102 if (current->pid != 0)
103 return -EPERM;
105 /* An endless idle loop with no priority at all. */
106 current->priority = 0;
107 current->counter = -100;
108 init_idle();
110 while (1) {
111 /* FIXME -- EV6 and LCA45 know how to power down
112 the CPU. */
114 schedule();
115 check_pgt_cache();
119 void
120 generic_kill_arch (int mode, char *restart_cmd)
122 /* The following currently only has any effect on SRM. We should
123 fix MILO to understand it. Should be pretty easy. Also we can
124 support RESTART2 via the ipc_buffer machinations pictured below,
125 which SRM ignores. */
127 if (alpha_using_srm) {
128 struct percpu_struct *cpup;
129 unsigned long flags;
131 cpup = (struct percpu_struct *)
132 ((unsigned long)hwrpb + hwrpb->processor_offset);
134 flags = cpup->flags;
136 /* Clear reason to "default"; clear "bootstrap in progress". */
137 flags &= ~0x00ff0001UL;
139 if (mode == LINUX_REBOOT_CMD_RESTART) {
140 if (!restart_cmd) {
141 flags |= 0x00020000UL; /* "cold bootstrap" */
142 cpup->ipc_buffer[0] = 0;
143 } else {
144 flags |= 0x00030000UL; /* "warm bootstrap" */
145 strncpy((char *)cpup->ipc_buffer, restart_cmd,
146 sizeof(cpup->ipc_buffer));
148 } else {
149 flags |= 0x00040000UL; /* "remain halted" */
152 cpup->flags = flags;
153 mb();
155 reset_for_srm();
156 set_hae(srm_hae);
158 #ifdef CONFIG_DUMMY_CONSOLE
159 /* This has the effect of reseting the VGA video origin. */
160 take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
161 #endif
164 #ifdef CONFIG_RTC
165 /* Reset rtc to defaults. */
167 unsigned char control;
169 cli();
171 /* Reset periodic interrupt frequency. */
172 CMOS_WRITE(0x26, RTC_FREQ_SELECT);
174 /* Turn on periodic interrupts. */
175 control = CMOS_READ(RTC_CONTROL);
176 control |= RTC_PIE;
177 CMOS_WRITE(control, RTC_CONTROL);
178 CMOS_READ(RTC_INTR_FLAGS);
180 sti();
182 #endif
184 if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
185 /* Unfortunately, since MILO doesn't currently understand
186 the hwrpb bits above, we can't reliably halt the
187 processor and keep it halted. So just loop. */
188 return;
191 if (alpha_using_srm)
192 srm_paging_stop();
194 halt();
197 void
198 machine_restart(char *restart_cmd)
200 alpha_mv.kill_arch(LINUX_REBOOT_CMD_RESTART, restart_cmd);
203 void
204 machine_halt(void)
206 alpha_mv.kill_arch(LINUX_REBOOT_CMD_HALT, NULL);
209 void machine_power_off(void)
211 alpha_mv.kill_arch(LINUX_REBOOT_CMD_POWER_OFF, NULL);
214 void show_regs(struct pt_regs * regs)
216 printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
217 printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
218 printk(" r0: %016lx r1: %016lx r2: %016lx r3: %016lx\n",
219 regs->r0, regs->r1, regs->r2, regs->r3);
220 printk(" r4: %016lx r5: %016lx r6: %016lx r7: %016lx\n",
221 regs->r4, regs->r5, regs->r6, regs->r7);
222 printk(" r8: %016lx r16: %016lx r17: %016lx r18: %016lx\n",
223 regs->r8, regs->r16, regs->r17, regs->r18);
224 printk("r19: %016lx r20: %016lx r21: %016lx r22: %016lx\n",
225 regs->r19, regs->r20, regs->r21, regs->r22);
226 printk("r23: %016lx r24: %016lx r25: %016lx r26: %016lx\n",
227 regs->r23, regs->r24, regs->r25, regs->r26);
228 printk("r27: %016lx r28: %016lx r29: %016lx hae: %016lx\n",
229 regs->r27, regs->r28, regs->gp, regs->hae);
233 * Re-start a thread when doing execve()
235 void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
237 set_fs(USER_DS);
238 regs->pc = pc;
239 regs->ps = 8;
240 wrusp(sp);
244 * Free current thread data structures etc..
246 void exit_thread(void)
250 void flush_thread(void)
252 /* Arrange for each exec'ed process to start off with a clean slate
253 with respect to the FPU. This is all exceptions disabled. Note
254 that EV6 defines UNFD valid only with UNDZ, which we don't want
255 for IEEE conformance -- so that disabled bit remains in software. */
257 current->thread.flags &= ~IEEE_SW_MASK;
258 wrfpcr(FPCR_DYN_NORMAL | FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_INED);
261 void release_thread(struct task_struct *dead_task)
266 * "alpha_clone()".. By the time we get here, the
267 * non-volatile registers have also been saved on the
268 * stack. We do some ugly pointer stuff here.. (see
269 * also copy_thread)
271 * Notice that "fork()" is implemented in terms of clone,
272 * with parameters (SIGCHLD, 0).
274 int alpha_clone(unsigned long clone_flags, unsigned long usp,
275 struct switch_stack * swstack)
277 if (!usp)
278 usp = rdusp();
279 return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
282 int alpha_vfork(struct switch_stack * swstack)
284 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
285 (struct pt_regs *) (swstack+1));
289 * Copy an alpha thread..
291 * Note the "stack_offset" stuff: when returning to kernel mode, we need
292 * to have some extra stack-space for the kernel stack that still exists
293 * after the "ret_from_sys_call". When returning to user mode, we only
294 * want the space needed by the syscall stack frame (ie "struct pt_regs").
295 * Use the passed "regs" pointer to determine how much space we need
296 * for a kernel fork().
299 int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
300 struct task_struct * p, struct pt_regs * regs)
302 extern void ret_from_sys_call(void);
303 extern void ret_from_smp_fork(void);
305 struct pt_regs * childregs;
306 struct switch_stack * childstack, *stack;
307 unsigned long stack_offset;
309 stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
310 if (!(regs->ps & 8))
311 stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
312 childregs = (struct pt_regs *) (stack_offset + PAGE_SIZE + (long)p);
314 *childregs = *regs;
315 childregs->r0 = 0;
316 childregs->r19 = 0;
317 childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
318 regs->r20 = 0;
319 stack = ((struct switch_stack *) regs) - 1;
320 childstack = ((struct switch_stack *) childregs) - 1;
321 *childstack = *stack;
322 #ifdef __SMP__
323 childstack->r26 = (unsigned long) ret_from_smp_fork;
324 #else
325 childstack->r26 = (unsigned long) ret_from_sys_call;
326 #endif
327 p->thread.usp = usp;
328 p->thread.ksp = (unsigned long) childstack;
329 p->thread.pal_flags = 1; /* set FEN, clear everything else */
330 p->thread.flags = current->thread.flags;
332 return 0;
336 * fill in the user structure for a core dump..
338 void dump_thread(struct pt_regs * pt, struct user * dump)
340 /* switch stack follows right below pt_regs: */
341 struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
343 dump->magic = CMAGIC;
344 dump->start_code = current->mm->start_code;
345 dump->start_data = current->mm->start_data;
346 dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
347 dump->u_tsize = ((current->mm->end_code - dump->start_code)
348 >> PAGE_SHIFT);
349 dump->u_dsize = ((current->mm->brk + PAGE_SIZE-1 - dump->start_data)
350 >> PAGE_SHIFT);
351 dump->u_ssize = (current->mm->start_stack - dump->start_stack
352 + PAGE_SIZE-1) >> PAGE_SHIFT;
355 * We store the registers in an order/format that is
356 * compatible with DEC Unix/OSF/1 as this makes life easier
357 * for gdb.
359 dump->regs[EF_V0] = pt->r0;
360 dump->regs[EF_T0] = pt->r1;
361 dump->regs[EF_T1] = pt->r2;
362 dump->regs[EF_T2] = pt->r3;
363 dump->regs[EF_T3] = pt->r4;
364 dump->regs[EF_T4] = pt->r5;
365 dump->regs[EF_T5] = pt->r6;
366 dump->regs[EF_T6] = pt->r7;
367 dump->regs[EF_T7] = pt->r8;
368 dump->regs[EF_S0] = sw->r9;
369 dump->regs[EF_S1] = sw->r10;
370 dump->regs[EF_S2] = sw->r11;
371 dump->regs[EF_S3] = sw->r12;
372 dump->regs[EF_S4] = sw->r13;
373 dump->regs[EF_S5] = sw->r14;
374 dump->regs[EF_S6] = sw->r15;
375 dump->regs[EF_A3] = pt->r19;
376 dump->regs[EF_A4] = pt->r20;
377 dump->regs[EF_A5] = pt->r21;
378 dump->regs[EF_T8] = pt->r22;
379 dump->regs[EF_T9] = pt->r23;
380 dump->regs[EF_T10] = pt->r24;
381 dump->regs[EF_T11] = pt->r25;
382 dump->regs[EF_RA] = pt->r26;
383 dump->regs[EF_T12] = pt->r27;
384 dump->regs[EF_AT] = pt->r28;
385 dump->regs[EF_SP] = rdusp();
386 dump->regs[EF_PS] = pt->ps;
387 dump->regs[EF_PC] = pt->pc;
388 dump->regs[EF_GP] = pt->gp;
389 dump->regs[EF_A0] = pt->r16;
390 dump->regs[EF_A1] = pt->r17;
391 dump->regs[EF_A2] = pt->r18;
392 memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
395 int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
397 /* switch stack follows right below pt_regs: */
398 struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
399 memcpy(r, sw->fp, 32 * 8);
400 return 1;
404 * sys_execve() executes a new program.
406 * This works due to the alpha calling sequence: the first 6 args
407 * are gotten from registers, while the rest is on the stack, so
408 * we get a0-a5 for free, and then magically find "struct pt_regs"
409 * on the stack for us..
411 * Don't do this at home.
413 asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
414 unsigned long a3, unsigned long a4, unsigned long a5,
415 struct pt_regs regs)
417 int error;
418 char * filename;
420 lock_kernel();
421 filename = getname((char *) a0);
422 error = PTR_ERR(filename);
423 if (IS_ERR(filename))
424 goto out;
425 error = do_execve(filename, (char **) a1, (char **) a2, &regs);
426 putname(filename);
427 out:
428 unlock_kernel();
429 return error;