OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [alpha/] [kernel/] [process.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 *  linux/arch/alpha/kernel/process.c
3
 *
4
 *  Copyright (C) 1995  Linus Torvalds
5
 */
6
 
7
/*
8
 * This file handles the architecture-dependent parts of process handling..
9
 */
10
 
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/stddef.h>
17
#include <linux/unistd.h>
18
#include <linux/ptrace.h>
19
#include <linux/malloc.h>
20
#include <linux/ldt.h>
21
#include <linux/user.h>
22
#include <linux/a.out.h>
23
#include <linux/utsname.h>
24
#include <linux/time.h>
25
#include <linux/major.h>
26
#include <linux/stat.h>
27
#include <linux/mman.h>
28
#include <linux/elfcore.h>
29
 
30
#include <asm/reg.h>
31
#include <asm/segment.h>
32
#include <asm/system.h>
33
#include <asm/io.h>
34
 
35
asmlinkage int sys_sethae(unsigned long hae, unsigned long a1,
36
                          unsigned long a2, unsigned long a3,
37
                          unsigned long a4, unsigned long a5,
38
        struct pt_regs regs)
39
{
40
        (&regs)->hae = hae;
41
        return 0;
42
}
43
 
44
asmlinkage int sys_idle(void)
45
{
46
        if (current->pid != 0)
47
                return -EPERM;
48
 
49
        /* endless idle loop with no priority at all */
50
        current->counter = -100;
51
        for (;;) {
52
                schedule();
53
        }
54
}
55
 
56
#include <asm/hwrpb.h>
57
 
58
static void swap_context(struct thread_struct * pcb)
59
{
60
        __asm__ __volatile__(
61
                "bis %0,%0,$16\n\t"
62
                "call_pal %1\n\t"
63
                : /* no outputs */
64
                : "r" (pcb), "i" (PAL_swpctx)
65
                : "$0", "$1", "$16", "$22", "$23", "$24", "$25");
66
}
67
 
68
void hard_reset_now(void)
69
{
70
#if defined(CONFIG_ALPHA_SRM_SETUP)
71
        extern void reset_for_srm(void);
72
        extern struct hwrpb_struct *hwrpb;
73
        extern struct thread_struct *original_pcb_ptr;
74
        struct percpu_struct *cpup;
75
        unsigned long flags;
76
 
77
        cpup = (struct percpu_struct *)
78
          ((unsigned long)hwrpb + hwrpb->processor_offset);
79
        flags = cpup->flags;
80
#if 1
81
        printk("hard_reset_now: flags 0x%lx\n", flags);
82
#endif
83
        flags &= ~0x0000000000ff0001UL; /* clear reason to "default" */
84
        flags |=  0x0000000000020000UL; /* this is "cold bootstrap" */
85
/*      flags |=  0x0000000000030000UL; *//* this is "warm bootstrap" */
86
/*      flags |=  0x0000000000040000UL; *//* this is "remain halted" */
87
        cpup->flags = flags;
88
        mb();
89
        reset_for_srm();
90
        swap_context(original_pcb_ptr);
91
#endif
92
#if defined(CONFIG_ALPHA_SRM) && defined(CONFIG_ALPHA_ALCOR)
93
        /* who said DEC engineer's have no sense of humor? ;-)) */
94
        *(int *) GRU_RESET = 0x0000dead;
95
        mb();
96
#endif
97
        halt();
98
}
99
 
100
void show_regs(struct pt_regs * regs)
101
{
102
        printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
103
        printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
104
        printk(" r0: %016lx  r1: %016lx  r2: %016lx  r3: %016lx\n",
105
               regs->r0, regs->r1, regs->r2, regs->r3);
106
        printk(" r4: %016lx  r5: %016lx  r6: %016lx  r7: %016lx\n",
107
               regs->r4, regs->r5, regs->r6, regs->r7);
108
        printk(" r8: %016lx r16: %016lx r17: %016lx r18: %016lx\n",
109
               regs->r8, regs->r16, regs->r17, regs->r18);
110
        printk("r19: %016lx r20: %016lx r21: %016lx r22: %016lx\n",
111
               regs->r19, regs->r20, regs->r21, regs->r22);
112
        printk("r23: %016lx r24: %016lx r25: %016lx r26: %016lx\n",
113
               regs->r23, regs->r24, regs->r25, regs->r26);
114
        printk("r27: %016lx r28: %016lx r29: %016lx hae: %016lx\n",
115
               regs->r27, regs->r28, regs->gp, regs->hae);
116
}
117
 
118
/*
119
 * Re-start a thread when doing execve()
120
 */
121
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
122
{
123
        set_fs(USER_DS);
124
        regs->pc = pc;
125
        regs->ps = 8;
126
        wrusp(sp);
127
}
128
 
129
/*
130
 * Free current thread data structures etc..
131
 */
132
void exit_thread(void)
133
{
134
}
135
 
136
void flush_thread(void)
137
{
138
}
139
 
140
void release_thread(struct task_struct *dead_task)
141
{
142
}
143
 
144
/*
145
 * "alpha_clone()".. By the time we get here, the
146
 * non-volatile registers have also been saved on the
147
 * stack. We do some ugly pointer stuff here.. (see
148
 * also copy_thread)
149
 *
150
 * Notice that "fork()" is implemented in terms of clone,
151
 * with parameters (SIGCHLD, 0).
152
 */
153
int alpha_clone(unsigned long clone_flags, unsigned long usp,
154
        struct switch_stack * swstack)
155
{
156
        if (!usp)
157
                usp = rdusp();
158
        return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
159
}
160
 
161
extern void ret_from_sys_call(void);
162
/*
163
 * Copy an alpha thread..
164
 *
165
 * Note the "stack_offset" stuff: when returning to kernel mode, we need
166
 * to have some extra stack-space for the kernel stack that still exists
167
 * after the "ret_from_sys_call". When returning to user mode, we only
168
 * want the space needed by the syscall stack frame (ie "struct pt_regs").
169
 * Use the passed "regs" pointer to determine how much space we need
170
 * for a kernel fork().
171
 */
172
void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
173
        struct task_struct * p, struct pt_regs * regs)
174
{
175
        struct pt_regs * childregs;
176
        struct switch_stack * childstack, *stack;
177
        unsigned long stack_offset;
178
 
179
        stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
180
        if (!(regs->ps & 8))
181
                stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
182
        childregs = (struct pt_regs *) (p->kernel_stack_page + stack_offset);
183
 
184
        *childregs = *regs;
185
        childregs->r0 = 0;
186
        childregs->r19 = 0;
187
        childregs->r20 = 1;     /* OSF/1 has some strange fork() semantics.. */
188
        regs->r20 = 0;
189
        stack = ((struct switch_stack *) regs) - 1;
190
        childstack = ((struct switch_stack *) childregs) - 1;
191
        *childstack = *stack;
192
        childstack->r26 = (unsigned long) ret_from_sys_call;
193
        p->tss.usp = usp;
194
        p->tss.ksp = (unsigned long) childstack;
195
        p->tss.pal_flags = 1;   /* set FEN, clear everything else */
196
        p->tss.flags = current->tss.flags;
197
        p->mm->context = 0;
198
}
199
 
200
/*
201
 * fill in the user structure for a core dump..
202
 */
203
void dump_thread(struct pt_regs * pt, struct user * dump)
204
{
205
        /* switch stack follows right below pt_regs: */
206
        struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
207
 
208
        dump->magic = CMAGIC;
209
        dump->start_code  = current->mm->start_code;
210
        dump->start_data  = current->mm->start_data;
211
        dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
212
        dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
213
        dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) >> PAGE_SHIFT;
214
        dump->u_ssize =
215
          (current->mm->start_stack - dump->start_stack + PAGE_SIZE - 1) >> PAGE_SHIFT;
216
 
217
        /*
218
         * We store the registers in an order/format that is
219
         * compatible with DEC Unix/OSF/1 as this makes life easier
220
         * for gdb.
221
         */
222
        dump->regs[EF_V0]  = pt->r0;
223
        dump->regs[EF_T0]  = pt->r1;
224
        dump->regs[EF_T1]  = pt->r2;
225
        dump->regs[EF_T2]  = pt->r3;
226
        dump->regs[EF_T3]  = pt->r4;
227
        dump->regs[EF_T4]  = pt->r5;
228
        dump->regs[EF_T5]  = pt->r6;
229
        dump->regs[EF_T6]  = pt->r7;
230
        dump->regs[EF_T7]  = pt->r8;
231
        dump->regs[EF_S0]  = sw->r9;
232
        dump->regs[EF_S1]  = sw->r10;
233
        dump->regs[EF_S2]  = sw->r11;
234
        dump->regs[EF_S3]  = sw->r12;
235
        dump->regs[EF_S4]  = sw->r13;
236
        dump->regs[EF_S5]  = sw->r14;
237
        dump->regs[EF_S6]  = sw->r15;
238
        dump->regs[EF_A3]  = pt->r19;
239
        dump->regs[EF_A4]  = pt->r20;
240
        dump->regs[EF_A5]  = pt->r21;
241
        dump->regs[EF_T8]  = pt->r22;
242
        dump->regs[EF_T9]  = pt->r23;
243
        dump->regs[EF_T10] = pt->r24;
244
        dump->regs[EF_T11] = pt->r25;
245
        dump->regs[EF_RA]  = pt->r26;
246
        dump->regs[EF_T12] = pt->r27;
247
        dump->regs[EF_AT]  = pt->r28;
248
        dump->regs[EF_SP]  = rdusp();
249
        dump->regs[EF_PS]  = pt->ps;
250
        dump->regs[EF_PC]  = pt->pc;
251
        dump->regs[EF_GP]  = pt->gp;
252
        dump->regs[EF_A0]  = pt->r16;
253
        dump->regs[EF_A1]  = pt->r17;
254
        dump->regs[EF_A2]  = pt->r18;
255
        memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
256
}
257
 
258
int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
259
{
260
        /* switch stack follows right below pt_regs: */
261
        struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
262
        memcpy(r, sw->fp, 32 * 8);
263
        return 1;
264
}
265
 
266
/*
267
 * sys_execve() executes a new program.
268
 *
269
 * This works due to the alpha calling sequence: the first 6 args
270
 * are gotten from registers, while the rest is on the stack, so
271
 * we get a0-a5 for free, and then magically find "struct pt_regs"
272
 * on the stack for us..
273
 *
274
 * Don't do this at home.
275
 */
276
asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
277
        unsigned long a3, unsigned long a4, unsigned long a5,
278
        struct pt_regs regs)
279
{
280
        int error;
281
        char * filename;
282
 
283
        error = getname((char *) a0, &filename);
284
        if (error)
285
                return error;
286
        error = do_execve(filename, (char **) a1, (char **) a2, &regs);
287
        putname(filename);
288
        return error;
289
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.