aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh64/kernel/process.c270
1 files changed, 13 insertions, 257 deletions
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index db475b7833fb..525d0ec19b78 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -20,261 +20,16 @@
20/* 20/*
21 * This file handles the architecture-dependent parts of process handling.. 21 * This file handles the architecture-dependent parts of process handling..
22 */ 22 */
23
24/* Temporary flags/tests. All to be removed/undefined. BEGIN */
25#define IDLE_TRACE
26#define VM_SHOW_TABLES
27#define VM_TEST_FAULT
28#define VM_TEST_RTLBMISS
29#define VM_TEST_WTLBMISS
30
31#undef VM_SHOW_TABLES
32#undef IDLE_TRACE
33/* Temporary flags/tests. All to be removed/undefined. END */
34
35#define __KERNEL_SYSCALLS__
36#include <stdarg.h>
37
38#include <linux/kernel.h>
39#include <linux/rwsem.h>
40#include <linux/mm.h> 23#include <linux/mm.h>
41#include <linux/smp.h>
42#include <linux/smp_lock.h>
43#include <linux/ptrace.h> 24#include <linux/ptrace.h>
44#include <linux/slab.h>
45#include <linux/vmalloc.h>
46#include <linux/user.h>
47#include <linux/a.out.h>
48#include <linux/interrupt.h>
49#include <linux/unistd.h>
50#include <linux/delay.h>
51#include <linux/reboot.h> 25#include <linux/reboot.h>
52#include <linux/init.h> 26#include <linux/init.h>
53 27#include <linux/module.h>
54#include <asm/uaccess.h> 28#include <asm/uaccess.h>
55#include <asm/pgtable.h> 29#include <asm/pgtable.h>
56#include <asm/system.h>
57#include <asm/io.h>
58#include <asm/processor.h> /* includes also <asm/registers.h> */
59#include <asm/mmu_context.h>
60#include <asm/elf.h>
61#include <asm/page.h>
62
63#include <linux/irq.h>
64 30
65struct task_struct *last_task_used_math = NULL; 31struct task_struct *last_task_used_math = NULL;
66 32
67#ifdef IDLE_TRACE
68#ifdef VM_SHOW_TABLES
69/* For testing */
70static void print_PTE(long base)
71{
72 int i, skip=0;
73 long long x, y, *p = (long long *) base;
74
75 for (i=0; i< 512; i++, p++){
76 if (*p == 0) {
77 if (!skip) {
78 skip++;
79 printk("(0s) ");
80 }
81 } else {
82 skip=0;
83 x = (*p) >> 32;
84 y = (*p) & 0xffffffff;
85 printk("%08Lx%08Lx ", x, y);
86 if (!((i+1)&0x3)) printk("\n");
87 }
88 }
89}
90
91/* For testing */
92static void print_DIR(long base)
93{
94 int i, skip=0;
95 long *p = (long *) base;
96
97 for (i=0; i< 512; i++, p++){
98 if (*p == 0) {
99 if (!skip) {
100 skip++;
101 printk("(0s) ");
102 }
103 } else {
104 skip=0;
105 printk("%08lx ", *p);
106 if (!((i+1)&0x7)) printk("\n");
107 }
108 }
109}
110
111/* For testing */
112static void print_vmalloc_first_tables(void)
113{
114
115#define PRESENT 0x800 /* Bit 11 */
116
117 /*
118 * Do it really dirty by looking at raw addresses,
119 * raw offsets, no types. If we used pgtable/pgalloc
120 * macros/definitions we could hide potential bugs.
121 *
122 * Note that pointers are 32-bit for CDC.
123 */
124 long pgdt, pmdt, ptet;
125
126 pgdt = (long) &swapper_pg_dir;
127 printk("-->PGD (0x%08lx):\n", pgdt);
128 print_DIR(pgdt);
129 printk("\n");
130
131 /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
132 pgdt += 4;
133 pmdt = (long) (* (long *) pgdt);
134 if (!(pmdt & PRESENT)) {
135 printk("No PMD\n");
136 return;
137 } else pmdt &= 0xfffff000;
138
139 printk("-->PMD (0x%08lx):\n", pmdt);
140 print_DIR(pmdt);
141 printk("\n");
142
143 /* Get the pmdt displacement for 0xc0000000 */
144 pmdt += 2048;
145
146 /* just look at first two address ranges ... */
147 /* ... 0xc0000000 ... */
148 ptet = (long) (* (long *) pmdt);
149 if (!(ptet & PRESENT)) {
150 printk("No PTE0\n");
151 return;
152 } else ptet &= 0xfffff000;
153
154 printk("-->PTE0 (0x%08lx):\n", ptet);
155 print_PTE(ptet);
156 printk("\n");
157
158 /* ... 0xc0001000 ... */
159 ptet += 4;
160 if (!(ptet & PRESENT)) {
161 printk("No PTE1\n");
162 return;
163 } else ptet &= 0xfffff000;
164 printk("-->PTE1 (0x%08lx):\n", ptet);
165 print_PTE(ptet);
166 printk("\n");
167}
168#else
169#define print_vmalloc_first_tables()
170#endif /* VM_SHOW_TABLES */
171
172static void test_VM(void)
173{
174 void *a, *b, *c;
175
176#ifdef VM_SHOW_TABLES
177 printk("Initial PGD/PMD/PTE\n");
178#endif
179 print_vmalloc_first_tables();
180
181 printk("Allocating 2 bytes\n");
182 a = vmalloc(2);
183 print_vmalloc_first_tables();
184
185 printk("Allocating 4100 bytes\n");
186 b = vmalloc(4100);
187 print_vmalloc_first_tables();
188
189 printk("Allocating 20234 bytes\n");
190 c = vmalloc(20234);
191 print_vmalloc_first_tables();
192
193#ifdef VM_TEST_FAULT
194 /* Here you may want to fault ! */
195
196#ifdef VM_TEST_RTLBMISS
197 printk("Ready to fault upon read.\n");
198 if (* (char *) a) {
199 printk("RTLBMISSed on area a !\n");
200 }
201 printk("RTLBMISSed on area a !\n");
202#endif
203
204#ifdef VM_TEST_WTLBMISS
205 printk("Ready to fault upon write.\n");
206 *((char *) b) = 'L';
207 printk("WTLBMISSed on area b !\n");
208#endif
209
210#endif /* VM_TEST_FAULT */
211
212 printk("Deallocating the 4100 byte chunk\n");
213 vfree(b);
214 print_vmalloc_first_tables();
215
216 printk("Deallocating the 2 byte chunk\n");
217 vfree(a);
218 print_vmalloc_first_tables();
219
220 printk("Deallocating the last chunk\n");
221 vfree(c);
222 print_vmalloc_first_tables();
223}
224
225extern unsigned long volatile jiffies;
226int once = 0;
227unsigned long old_jiffies;
228int pid = -1, pgid = -1;
229
230void idle_trace(void)
231{
232
233 _syscall0(int, getpid)
234 _syscall1(int, getpgid, int, pid)
235
236 if (!once) {
237 /* VM allocation/deallocation simple test */
238 test_VM();
239 pid = getpid();
240
241 printk("Got all through to Idle !!\n");
242 printk("I'm now going to loop forever ...\n");
243 printk("Any ! below is a timer tick.\n");
244 printk("Any . below is a getpgid system call from pid = %d.\n", pid);
245
246
247 old_jiffies = jiffies;
248 once++;
249 }
250
251 if (old_jiffies != jiffies) {
252 old_jiffies = jiffies - old_jiffies;
253 switch (old_jiffies) {
254 case 1:
255 printk("!");
256 break;
257 case 2:
258 printk("!!");
259 break;
260 case 3:
261 printk("!!!");
262 break;
263 case 4:
264 printk("!!!!");
265 break;
266 default:
267 printk("(%d!)", (int) old_jiffies);
268 }
269 old_jiffies = jiffies;
270 }
271 pgid = getpgid(pid);
272 printk(".");
273}
274#else
275#define idle_trace() do { } while (0)
276#endif /* IDLE_TRACE */
277
278static int hlt_counter = 1; 33static int hlt_counter = 1;
279 34
280#define HARD_IDLE_TIMEOUT (HZ / 3) 35#define HARD_IDLE_TIMEOUT (HZ / 3)
@@ -323,7 +78,6 @@ void cpu_idle(void)
323 local_irq_disable(); 78 local_irq_disable();
324 while (!need_resched()) { 79 while (!need_resched()) {
325 local_irq_enable(); 80 local_irq_enable();
326 idle_trace();
327 hlt(); 81 hlt();
328 local_irq_disable(); 82 local_irq_disable();
329 } 83 }
@@ -622,6 +376,10 @@ void free_task_struct(struct task_struct *p)
622/* 376/*
623 * Create a kernel thread 377 * Create a kernel thread
624 */ 378 */
379ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
380{
381 do_exit(fn(arg));
382}
625 383
626/* 384/*
627 * This is the mechanism for creating a new kernel thread. 385 * This is the mechanism for creating a new kernel thread.
@@ -633,19 +391,17 @@ void free_task_struct(struct task_struct *p)
633 */ 391 */
634int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 392int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
635{ 393{
636 /* A bit less processor dependent than older sh ... */ 394 struct pt_regs regs;
637 unsigned int reply;
638 395
639static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp) 396 memset(&regs, 0, sizeof(regs));
640static __inline__ _syscall1(int,exit,int,ret) 397 regs.regs[2] = (unsigned long)arg;
398 regs.regs[3] = (unsigned long)fn;
641 399
642 reply = clone(flags | CLONE_VM, 0); 400 regs.pc = (unsigned long)kernel_thread_helper;
643 if (!reply) { 401 regs.sr = (1 << 30);
644 /* Child */
645 reply = exit(fn(arg));
646 }
647 402
648 return reply; 403 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
404 &regs, 0, NULL, NULL);
649} 405}
650 406
651/* 407/*