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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/*
2
 *  linux/arch/ppc/kernel/process.c
3
 *
4
 *  Copyright (C) 1995  Linus Torvalds
5
 *  Adapted for PowerPC by Gary Thomas
6
 */
7
 
8
/*
9
 * This file handles the architecture-dependent parts of process handling..
10
 */
11
 
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
 
24
#include <asm/pgtable.h>
25
#include <asm/segment.h>
26
#include <asm/system.h>
27
#include <asm/io.h>
28
 
29
#include <asm/ppc_machine.h>
30
 
31
int
32
dump_fpu()
33
{
34
        return (1);
35
}
36
 
37
void
38
switch_to(struct task_struct *prev, struct task_struct *new)
39
{
40
        struct pt_regs *regs;
41
        struct thread_struct *new_tss, *old_tss;
42
        int s = _disable_interrupts();
43
        regs = new->tss.ksp;
44
#if 0
45
        printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid);
46
        printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs);
47
#endif
48
        new_tss = &new->tss;
49
        old_tss = &current->tss;
50
        current_set[0] = new;    /* FIX ME! */
51
        _switch(old_tss, new_tss);
52
#if 0
53
        printk("Back in task %x(%d)\n", current, current->pid);
54
#endif
55
        _enable_interrupts(s);
56
}
57
 
58
asmlinkage int sys_idle(void)
59
{
60
        if (current->pid != 0)
61
                return -EPERM;
62
 
63
        /* endless idle loop with no priority at all */
64
        current->counter = -100;
65
        for (;;) {
66
                schedule();
67
        }
68
}
69
 
70
void hard_reset_now(void)
71
{
72
        halt();
73
}
74
 
75
void show_regs(struct pt_regs * regs)
76
{
77
        _panic("show_regs");
78
}
79
 
80
/*
81
 * Free current thread data structures etc..
82
 */
83
void exit_thread(void)
84
{
85
}
86
 
87
void flush_thread(void)
88
{
89
}
90
 
91
void
92
release_thread(struct task_struct *t)
93
{
94
}
95
 
96
/*
97
 * Copy a thread..
98
 */
99
void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
100
        struct task_struct * p, struct pt_regs * regs)
101
{
102
        int i;
103
        SEGREG *segs;
104
        struct pt_regs * childregs;
105
#if 0
106
printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs);
107
#endif
108
        /* Construct segment registers */
109
        segs = p->tss.segs;
110
        for (i = 0;  i < 8;  i++)
111
        {
112
                segs[i].ks = 0;
113
                segs[i].kp = 1;
114
                segs[i].vsid = i | (nr << 4);
115
        }
116
        if ((p->mm->context == 0) || (p->mm->count == 1))
117
        {
118
                p->mm->context = (nr<<4);
119
#if 0           
120
printk("Setting MM[%x] Context = %x Task = %x Current = %x/%x\n", p->mm, p->mm->context, p, current, current->mm);
121
#endif
122
        }
123
        /* Last 8 are shared with kernel & everybody else... */
124
        for (i = 8;  i < 16;  i++)
125
        {
126
                segs[i].ks = 0;
127
                segs[i].kp = 1;
128
                segs[i].vsid = i;
129
        }
130
        /* Copy registers */
131
#ifdef STACK_HAS_TWO_PAGES
132
        childregs = ((struct pt_regs *) (p->kernel_stack_page + 2*PAGE_SIZE)) - 2;
133
#else   
134
        childregs = ((struct pt_regs *) (p->kernel_stack_page + 1*PAGE_SIZE)) - 2;
135
#endif  
136
        *childregs = *regs;     /* STRUCT COPY */
137
        childregs->gpr[3] = 0;  /* Result from fork() */
138
        p->tss.ksp = childregs;
139
        if (usp >= (unsigned long)regs)
140
        { /* Stack is in kernel space - must adjust */
141
                childregs->gpr[1] = childregs+1;
142
        } else
143
        { /* Provided stack is in user space */
144
                childregs->gpr[1] = usp;
145
        }
146
}
147
 
148
/*
149
 * fill in the user structure for a core dump..
150
 */
151
void dump_thread(struct pt_regs * regs, struct user * dump)
152
{
153
}
154
 
155
#if 0
156
/*
157
 * Do necessary setup to start up a newly executed thread.
158
 */
159
void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
160
{
161
        regs->nip = eip;
162
        regs->gpr[1] = esp;
163
        regs->msr = MSR_USER;
164
#if 0
165
{
166
        int len;
167
        len = (unsigned long)0x80000000 - esp;
168
        if (len > 128) len = 128;
169
        printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n", regs, eip, regs->msr, esp);
170
        dump_buf(esp, len);
171
        dump_buf(eip, 0x80);
172
}
173
#endif  
174
}
175
#endif
176
 
177
asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
178
{
179
        return do_fork(SIGCHLD, regs->gpr[1], regs);
180
}
181
 
182
/*
183
 * sys_execve() executes a new program.
184
 *
185
 * This works due to the PowerPC calling sequence: the first 6 args
186
 * are gotten from registers, while the rest is on the stack, so
187
 * we get a0-a5 for free, and then magically find "struct pt_regs"
188
 * on the stack for us..
189
 *
190
 * Don't do this at home.
191
 */
192
asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
193
        unsigned long a3, unsigned long a4, unsigned long a5,
194
        struct pt_regs *regs)
195
{
196
        int error;
197
        char * filename;
198
 
199
        error = getname((char *) a0, &filename);
200
        if (error)
201
        {
202
printk("Error getting EXEC name: %d\n", error);
203
                return error;
204
        }
205
        flush_instruction_cache();
206
        error = do_execve(filename, (char **) a1, (char **) a2, regs);
207
#if 0
208
if (error)
209
{
210
printk("EXECVE - file = '%s', error = %d\n", filename, error);
211
}
212
#endif
213
        putname(filename);
214
        return error;
215
}
216
 
217
/*
218
 * This doesn't actually work correctly like this: we need to do the
219
 * same stack setups that fork() does first.
220
 */
221
asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
222
{
223
        unsigned long clone_flags = p1;
224
        int res;
225
        res = do_fork(clone_flags, regs->gpr[1], regs);
226
        return res;
227
}
228
 
229
void
230
print_backtrace(unsigned long *sp)
231
{
232
        int cnt = 0;
233
        printk("... Call backtrace:\n");
234
        while (*sp)
235
        {
236
                printk("%08X ", sp[1]);
237
                sp = *sp;
238
                if (++cnt == 8)
239
                {
240
                        printk("\n");
241
                }
242
                if (cnt > 32) break;
243
        }
244
        printk("\n");
245
}
246
 
247
void
248
print_user_backtrace(unsigned long *sp)
249
{
250
        int cnt = 0;
251
        printk("... [User] Call backtrace:\n");
252
        while (valid_addr(sp) && *sp)
253
        {
254
                printk("%08X ", sp[1]);
255
                sp = *sp;
256
                if (++cnt == 8)
257
                {
258
                        printk("\n");
259
                }
260
                if (cnt > 16) break;
261
        }
262
        printk("\n");
263
}
264
 
265
void
266
print_kernel_backtrace(void)
267
{
268
        unsigned long *_get_SP(void);
269
        print_backtrace(_get_SP());
270
}

powered by: WebSVN 2.1.0

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