diff options
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r-- | arch/mips/kernel/process.c | 53 |
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 | ||
54 | void 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 | |||
67 | asmlinkage void ret_from_fork(void); | 54 | asmlinkage void ret_from_fork(void); |
68 | asmlinkage void ret_from_kernel_thread(void); | 55 | asmlinkage 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 | |||
227 | static inline int is_ra_save_ins(union mips_instruction *ip) | 217 | static 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 | ||
267 | static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) | 257 | static 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 | ||
394 | static struct mips_frame_info schedule_mfi __read_mostly; | 386 | static struct mips_frame_info schedule_mfi __read_mostly; |
395 | 387 | ||
388 | #ifdef CONFIG_KALLSYMS | ||
389 | static unsigned long get___schedule_addr(void) | ||
390 | { | ||
391 | return kallsyms_lookup_name("__schedule"); | ||
392 | } | ||
393 | #else | ||
394 | static 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 | |||
396 | static int __init frame_info_init(void) | 408 | static 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); |