aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r--arch/mips/kernel/process.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index eb902c1f0cad..c6a041d9d05d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -51,19 +51,6 @@ void arch_cpu_idle_dead(void)
51} 51}
52#endif 52#endif
53 53
54void arch_cpu_idle(void)
55{
56#ifdef CONFIG_MIPS_MT_SMTC
57 extern void smtc_idle_loop_hook(void);
58
59 smtc_idle_loop_hook();
60#endif
61 if (cpu_wait)
62 (*cpu_wait)();
63 else
64 local_irq_enable();
65}
66
67asmlinkage void ret_from_fork(void); 54asmlinkage void ret_from_fork(void);
68asmlinkage void ret_from_kernel_thread(void); 55asmlinkage void ret_from_kernel_thread(void);
69 56
@@ -224,6 +211,9 @@ struct mips_frame_info {
224 int pc_offset; 211 int pc_offset;
225}; 212};
226 213
214#define J_TARGET(pc,target) \
215 (((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
216
227static inline int is_ra_save_ins(union mips_instruction *ip) 217static inline int is_ra_save_ins(union mips_instruction *ip)
228{ 218{
229#ifdef CONFIG_CPU_MICROMIPS 219#ifdef CONFIG_CPU_MICROMIPS
@@ -264,7 +254,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
264#endif 254#endif
265} 255}
266 256
267static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) 257static inline int is_jump_ins(union mips_instruction *ip)
268{ 258{
269#ifdef CONFIG_CPU_MICROMIPS 259#ifdef CONFIG_CPU_MICROMIPS
270 /* 260 /*
@@ -288,6 +278,8 @@ static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
288 return 0; 278 return 0;
289 return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); 279 return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op);
290#else 280#else
281 if (ip->j_format.opcode == j_op)
282 return 1;
291 if (ip->j_format.opcode == jal_op) 283 if (ip->j_format.opcode == jal_op)
292 return 1; 284 return 1;
293 if (ip->r_format.opcode != spec_op) 285 if (ip->r_format.opcode != spec_op)
@@ -350,7 +342,7 @@ static int get_frame_info(struct mips_frame_info *info)
350 342
351 for (i = 0; i < max_insns; i++, ip++) { 343 for (i = 0; i < max_insns; i++, ip++) {
352 344
353 if (is_jal_jalr_jr_ins(ip)) 345 if (is_jump_ins(ip))
354 break; 346 break;
355 if (!info->frame_size) { 347 if (!info->frame_size) {
356 if (is_sp_move_ins(ip)) 348 if (is_sp_move_ins(ip))
@@ -393,15 +385,42 @@ err:
393 385
394static struct mips_frame_info schedule_mfi __read_mostly; 386static struct mips_frame_info schedule_mfi __read_mostly;
395 387
388#ifdef CONFIG_KALLSYMS
389static unsigned long get___schedule_addr(void)
390{
391 return kallsyms_lookup_name("__schedule");
392}
393#else
394static unsigned long get___schedule_addr(void)
395{
396 union mips_instruction *ip = (void *)schedule;
397 int max_insns = 8;
398 int i;
399
400 for (i = 0; i < max_insns; i++, ip++) {
401 if (ip->j_format.opcode == j_op)
402 return J_TARGET(ip, ip->j_format.target);
403 }
404 return 0;
405}
406#endif
407
396static int __init frame_info_init(void) 408static int __init frame_info_init(void)
397{ 409{
398 unsigned long size = 0; 410 unsigned long size = 0;
399#ifdef CONFIG_KALLSYMS 411#ifdef CONFIG_KALLSYMS
400 unsigned long ofs; 412 unsigned long ofs;
413#endif
414 unsigned long addr;
415
416 addr = get___schedule_addr();
417 if (!addr)
418 addr = (unsigned long)schedule;
401 419
402 kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); 420#ifdef CONFIG_KALLSYMS
421 kallsyms_lookup_size_offset(addr, &size, &ofs);
403#endif 422#endif
404 schedule_mfi.func = schedule; 423 schedule_mfi.func = (void *)addr;
405 schedule_mfi.func_size = size; 424 schedule_mfi.func_size = size;
406 425
407 get_frame_info(&schedule_mfi); 426 get_frame_info(&schedule_mfi);