diff options
Diffstat (limited to 'firmware/thread.c')
-rw-r--r-- | firmware/thread.c | 82 |
1 files changed, 34 insertions, 48 deletions
diff --git a/firmware/thread.c b/firmware/thread.c index 259a66a652..2ac7f6efc3 100644 --- a/firmware/thread.c +++ b/firmware/thread.c | |||
@@ -399,7 +399,7 @@ static inline void core_sleep(void) | |||
399 | { | 399 | { |
400 | PROC_CTL(CURRENT_CORE) = PROC_SLEEP; | 400 | PROC_CTL(CURRENT_CORE) = PROC_SLEEP; |
401 | nop; nop; nop; | 401 | nop; nop; nop; |
402 | set_irq_level(IRQ_ENABLED); | 402 | enable_irq(); |
403 | } | 403 | } |
404 | #else | 404 | #else |
405 | static inline void core_sleep(unsigned int core) | 405 | static inline void core_sleep(unsigned int core) |
@@ -421,9 +421,6 @@ static inline void core_sleep(unsigned int core) | |||
421 | "ldr r1, [%[mbx], #0] \n" | 421 | "ldr r1, [%[mbx], #0] \n" |
422 | "tst r1, r0, lsr #2 \n" | 422 | "tst r1, r0, lsr #2 \n" |
423 | "bne 1b \n" | 423 | "bne 1b \n" |
424 | "mrs r1, cpsr \n" /* Enable IRQ */ | ||
425 | "bic r1, r1, #0x80 \n" | ||
426 | "msr cpsr_c, r1 \n" | ||
427 | : | 424 | : |
428 | : [ctl]"r"(&PROC_CTL(CPU)), [mbx]"r"(MBX_BASE), [c]"r"(core) | 425 | : [ctl]"r"(&PROC_CTL(CPU)), [mbx]"r"(MBX_BASE), [c]"r"(core) |
429 | : "r0", "r1"); | 426 | : "r0", "r1"); |
@@ -443,10 +440,8 @@ static inline void core_sleep(unsigned int core) | |||
443 | 440 | ||
444 | /* Wait for other processor to finish wake procedure */ | 441 | /* Wait for other processor to finish wake procedure */ |
445 | while (MBX_MSG_STAT & (0x1 << core)); | 442 | while (MBX_MSG_STAT & (0x1 << core)); |
446 | |||
447 | /* Enable IRQ */ | ||
448 | set_irq_level(IRQ_ENABLED); | ||
449 | #endif /* ASM/C selection */ | 443 | #endif /* ASM/C selection */ |
444 | enable_irq(); | ||
450 | } | 445 | } |
451 | #endif /* NUM_CORES */ | 446 | #endif /* NUM_CORES */ |
452 | #elif CONFIG_CPU == PP5002 | 447 | #elif CONFIG_CPU == PP5002 |
@@ -465,13 +460,11 @@ static inline void core_sleep(void) | |||
465 | "nop \n" /* nop's needed because of pipeline */ | 460 | "nop \n" /* nop's needed because of pipeline */ |
466 | "nop \n" | 461 | "nop \n" |
467 | "nop \n" | 462 | "nop \n" |
468 | "mrs r0, cpsr \n" /* Enable IRQ */ | ||
469 | "bic r0, r0, #0x80 \n" | ||
470 | "msr cpsr_c, r0 \n" | ||
471 | : | 463 | : |
472 | : [ctl]"r"(&PROC_CTL(CURRENT_CORE)) | 464 | : [ctl]"r"(&PROC_CTL(CURRENT_CORE)) |
473 | : "r0" | 465 | : "r0" |
474 | ); | 466 | ); |
467 | enable_irq(); | ||
475 | } | 468 | } |
476 | #else | 469 | #else |
477 | /* PP5002 has no mailboxes - emulate using bytes */ | 470 | /* PP5002 has no mailboxes - emulate using bytes */ |
@@ -503,9 +496,6 @@ static inline void core_sleep(unsigned int core) | |||
503 | "ldrb r0, [%[sem], #0] \n" | 496 | "ldrb r0, [%[sem], #0] \n" |
504 | "cmp r0, #0 \n" | 497 | "cmp r0, #0 \n" |
505 | "bne 1b \n" | 498 | "bne 1b \n" |
506 | "mrs r0, cpsr \n" /* Enable IRQ */ | ||
507 | "bic r0, r0, #0x80 \n" | ||
508 | "msr cpsr_c, r0 \n" | ||
509 | : | 499 | : |
510 | : [sem]"r"(&core_semaphores[core]), [c]"r"(core), | 500 | : [sem]"r"(&core_semaphores[core]), [c]"r"(core), |
511 | [ctl]"r"(&PROC_CTL(CPU)) | 501 | [ctl]"r"(&PROC_CTL(CPU)) |
@@ -530,8 +520,8 @@ static inline void core_sleep(unsigned int core) | |||
530 | while (core_semaphores[core].intend_wake != 0); | 520 | while (core_semaphores[core].intend_wake != 0); |
531 | 521 | ||
532 | /* Enable IRQ */ | 522 | /* Enable IRQ */ |
533 | set_irq_level(IRQ_ENABLED); | ||
534 | #endif /* ASM/C selection */ | 523 | #endif /* ASM/C selection */ |
524 | enable_irq(); | ||
535 | } | 525 | } |
536 | #endif /* NUM_CORES */ | 526 | #endif /* NUM_CORES */ |
537 | #endif /* PP CPU type */ | 527 | #endif /* PP CPU type */ |
@@ -578,7 +568,7 @@ void core_wake(unsigned int othercore) | |||
578 | : "r1", "r2", "r3"); | 568 | : "r1", "r2", "r3"); |
579 | #else /* C version for reference */ | 569 | #else /* C version for reference */ |
580 | /* Disable interrupts - avoid reentrancy from the tick */ | 570 | /* Disable interrupts - avoid reentrancy from the tick */ |
581 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 571 | int oldlevel = disable_irq_save(); |
582 | 572 | ||
583 | /* Signal intent to wake other processor - set stay awake */ | 573 | /* Signal intent to wake other processor - set stay awake */ |
584 | MBX_MSG_SET = 0x11 << othercore; | 574 | MBX_MSG_SET = 0x11 << othercore; |
@@ -593,7 +583,7 @@ void core_wake(unsigned int othercore) | |||
593 | 583 | ||
594 | /* Done with wake procedure */ | 584 | /* Done with wake procedure */ |
595 | MBX_MSG_CLR = 0x1 << othercore; | 585 | MBX_MSG_CLR = 0x1 << othercore; |
596 | set_irq_level(oldlevel); | 586 | restore_irq(oldlevel); |
597 | #endif /* ASM/C selection */ | 587 | #endif /* ASM/C selection */ |
598 | } | 588 | } |
599 | #elif CONFIG_CPU == PP5002 | 589 | #elif CONFIG_CPU == PP5002 |
@@ -631,7 +621,7 @@ void core_wake(unsigned int othercore) | |||
631 | ); | 621 | ); |
632 | #else /* C version for reference */ | 622 | #else /* C version for reference */ |
633 | /* Disable interrupts - avoid reentrancy from the tick */ | 623 | /* Disable interrupts - avoid reentrancy from the tick */ |
634 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 624 | int oldlevel = disable_irq_save(); |
635 | 625 | ||
636 | /* Signal intent to wake other processor - set stay awake */ | 626 | /* Signal intent to wake other processor - set stay awake */ |
637 | core_semaphores[othercore].intend_wake = 1; | 627 | core_semaphores[othercore].intend_wake = 1; |
@@ -647,7 +637,7 @@ void core_wake(unsigned int othercore) | |||
647 | 637 | ||
648 | /* Done with wake procedure */ | 638 | /* Done with wake procedure */ |
649 | core_semaphores[othercore].intend_wake = 0; | 639 | core_semaphores[othercore].intend_wake = 0; |
650 | set_irq_level(oldlevel); | 640 | restore_irq(oldlevel); |
651 | #endif /* ASM/C selection */ | 641 | #endif /* ASM/C selection */ |
652 | } | 642 | } |
653 | #endif /* CPU type */ | 643 | #endif /* CPU type */ |
@@ -775,7 +765,7 @@ static inline void core_sleep(void) | |||
775 | static inline void core_sleep(void) | 765 | static inline void core_sleep(void) |
776 | { | 766 | { |
777 | #warning TODO: Implement core_sleep | 767 | #warning TODO: Implement core_sleep |
778 | set_irq_level(IRQ_ENABLED); | 768 | enable_irq(); |
779 | } | 769 | } |
780 | #elif defined(CPU_TCC780X) | 770 | #elif defined(CPU_TCC780X) |
781 | static inline void core_sleep(void) | 771 | static inline void core_sleep(void) |
@@ -784,11 +774,9 @@ static inline void core_sleep(void) | |||
784 | asm volatile ( | 774 | asm volatile ( |
785 | "mov r0, #0 \n" | 775 | "mov r0, #0 \n" |
786 | "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */ | 776 | "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */ |
787 | "mrs r0, cpsr \n" /* Unmask IRQ at core level */ | ||
788 | "bic r0, r0, #0x80 \n" | ||
789 | "msr cpsr_c, r0 \n" | ||
790 | : : : "r0" | 777 | : : : "r0" |
791 | ); | 778 | ); |
779 | enable_irq(); | ||
792 | } | 780 | } |
793 | #elif CONFIG_CPU == IMX31L | 781 | #elif CONFIG_CPU == IMX31L |
794 | static inline void core_sleep(void) | 782 | static inline void core_sleep(void) |
@@ -796,17 +784,15 @@ static inline void core_sleep(void) | |||
796 | asm volatile ( | 784 | asm volatile ( |
797 | "mov r0, #0 \n" | 785 | "mov r0, #0 \n" |
798 | "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */ | 786 | "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */ |
799 | "mrs r0, cpsr \n" /* Unmask IRQ at core level */ | ||
800 | "bic r0, r0, #0x80 \n" | ||
801 | "msr cpsr_c, r0 \n" | ||
802 | : : : "r0" | 787 | : : : "r0" |
803 | ); | 788 | ); |
789 | enable_irq(); | ||
804 | } | 790 | } |
805 | #else | 791 | #else |
806 | static inline void core_sleep(void) | 792 | static inline void core_sleep(void) |
807 | { | 793 | { |
808 | #warning core_sleep not implemented, battery life will be decreased | 794 | #warning core_sleep not implemented, battery life will be decreased |
809 | set_irq_level(0); | 795 | enable_irq(); |
810 | } | 796 | } |
811 | #endif /* CONFIG_CPU == */ | 797 | #endif /* CONFIG_CPU == */ |
812 | 798 | ||
@@ -1706,14 +1692,14 @@ void check_tmo_threads(void) | |||
1706 | while (next != NULL) | 1692 | while (next != NULL) |
1707 | { | 1693 | { |
1708 | /* Check sleeping threads. Allow interrupts between checks. */ | 1694 | /* Check sleeping threads. Allow interrupts between checks. */ |
1709 | set_irq_level(0); | 1695 | enable_irq(); |
1710 | 1696 | ||
1711 | struct thread_entry *curr = next; | 1697 | struct thread_entry *curr = next; |
1712 | 1698 | ||
1713 | next = curr->tmo.next; | 1699 | next = curr->tmo.next; |
1714 | 1700 | ||
1715 | /* Lock thread slot against explicit wakeup */ | 1701 | /* Lock thread slot against explicit wakeup */ |
1716 | set_irq_level(HIGHEST_IRQ_LEVEL); | 1702 | disable_irq(); |
1717 | LOCK_THREAD(curr); | 1703 | LOCK_THREAD(curr); |
1718 | 1704 | ||
1719 | unsigned state = curr->state; | 1705 | unsigned state = curr->state; |
@@ -1956,7 +1942,7 @@ void switch_thread(void) | |||
1956 | check_tmo_threads(); | 1942 | check_tmo_threads(); |
1957 | } | 1943 | } |
1958 | 1944 | ||
1959 | set_irq_level(HIGHEST_IRQ_LEVEL); | 1945 | disable_irq(); |
1960 | RTR_LOCK(core); | 1946 | RTR_LOCK(core); |
1961 | 1947 | ||
1962 | thread = cores[core].running; | 1948 | thread = cores[core].running; |
@@ -2018,7 +2004,7 @@ void switch_thread(void) | |||
2018 | #endif /* HAVE_PRIORITY_SCHEDULING */ | 2004 | #endif /* HAVE_PRIORITY_SCHEDULING */ |
2019 | 2005 | ||
2020 | RTR_UNLOCK(core); | 2006 | RTR_UNLOCK(core); |
2021 | set_irq_level(0); | 2007 | enable_irq(); |
2022 | break; | 2008 | break; |
2023 | } | 2009 | } |
2024 | } | 2010 | } |
@@ -2212,7 +2198,7 @@ unsigned int thread_queue_wake(struct thread_entry **list) | |||
2212 | static struct thread_entry * find_empty_thread_slot(void) | 2198 | static struct thread_entry * find_empty_thread_slot(void) |
2213 | { | 2199 | { |
2214 | /* Any slot could be on an interrupt-accessible list */ | 2200 | /* Any slot could be on an interrupt-accessible list */ |
2215 | IF_COP( int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); ) | 2201 | IF_COP( int oldlevel = disable_irq_save(); ) |
2216 | struct thread_entry *thread = NULL; | 2202 | struct thread_entry *thread = NULL; |
2217 | int n; | 2203 | int n; |
2218 | 2204 | ||
@@ -2233,7 +2219,7 @@ static struct thread_entry * find_empty_thread_slot(void) | |||
2233 | UNLOCK_THREAD(t); | 2219 | UNLOCK_THREAD(t); |
2234 | } | 2220 | } |
2235 | 2221 | ||
2236 | IF_COP( set_irq_level(oldlevel); ) /* Reenable interrups - this slot is | 2222 | IF_COP( restore_irq(oldlevel); ) /* Reenable interrups - this slot is |
2237 | not accesible to them yet */ | 2223 | not accesible to them yet */ |
2238 | return thread; | 2224 | return thread; |
2239 | } | 2225 | } |
@@ -2247,7 +2233,7 @@ static struct thread_entry * find_empty_thread_slot(void) | |||
2247 | void core_idle(void) | 2233 | void core_idle(void) |
2248 | { | 2234 | { |
2249 | IF_COP( const unsigned int core = CURRENT_CORE; ) | 2235 | IF_COP( const unsigned int core = CURRENT_CORE; ) |
2250 | set_irq_level(HIGHEST_IRQ_LEVEL); | 2236 | disable_irq(); |
2251 | core_sleep(IF_COP(core)); | 2237 | core_sleep(IF_COP(core)); |
2252 | } | 2238 | } |
2253 | 2239 | ||
@@ -2277,7 +2263,7 @@ struct thread_entry* | |||
2277 | return NULL; | 2263 | return NULL; |
2278 | } | 2264 | } |
2279 | 2265 | ||
2280 | oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 2266 | oldlevel = disable_irq_save(); |
2281 | 2267 | ||
2282 | /* Munge the stack to make it easy to spot stack overflows */ | 2268 | /* Munge the stack to make it easy to spot stack overflows */ |
2283 | stackptr = ALIGN_UP((uintptr_t)stack, sizeof (uintptr_t)); | 2269 | stackptr = ALIGN_UP((uintptr_t)stack, sizeof (uintptr_t)); |
@@ -2338,7 +2324,7 @@ struct thread_entry* | |||
2338 | 2324 | ||
2339 | UNLOCK_THREAD(thread); | 2325 | UNLOCK_THREAD(thread); |
2340 | 2326 | ||
2341 | set_irq_level(oldlevel); | 2327 | restore_irq(oldlevel); |
2342 | 2328 | ||
2343 | return thread; | 2329 | return thread; |
2344 | } | 2330 | } |
@@ -2394,7 +2380,7 @@ void thread_wait(struct thread_entry *thread) | |||
2394 | IF_COP( current->obj_cl = &thread->waiter_cl; ) | 2380 | IF_COP( current->obj_cl = &thread->waiter_cl; ) |
2395 | current->bqp = &thread->queue; | 2381 | current->bqp = &thread->queue; |
2396 | 2382 | ||
2397 | set_irq_level(HIGHEST_IRQ_LEVEL); | 2383 | disable_irq(); |
2398 | block_thread(current); | 2384 | block_thread(current); |
2399 | 2385 | ||
2400 | corelock_unlock(&thread->waiter_cl); | 2386 | corelock_unlock(&thread->waiter_cl); |
@@ -2418,7 +2404,7 @@ void thread_exit(void) | |||
2418 | /* Cancel CPU boost if any */ | 2404 | /* Cancel CPU boost if any */ |
2419 | cancel_cpu_boost(); | 2405 | cancel_cpu_boost(); |
2420 | 2406 | ||
2421 | set_irq_level(HIGHEST_IRQ_LEVEL); | 2407 | disable_irq(); |
2422 | 2408 | ||
2423 | corelock_lock(¤t->waiter_cl); | 2409 | corelock_lock(¤t->waiter_cl); |
2424 | LOCK_THREAD(current); | 2410 | LOCK_THREAD(current); |
@@ -2503,7 +2489,7 @@ void remove_thread(struct thread_entry *thread) | |||
2503 | if (thread == current) | 2489 | if (thread == current) |
2504 | thread_exit(); /* Current thread - do normal exit */ | 2490 | thread_exit(); /* Current thread - do normal exit */ |
2505 | 2491 | ||
2506 | oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 2492 | oldlevel = disable_irq_save(); |
2507 | 2493 | ||
2508 | corelock_lock(&thread->waiter_cl); | 2494 | corelock_lock(&thread->waiter_cl); |
2509 | LOCK_THREAD(thread); | 2495 | LOCK_THREAD(thread); |
@@ -2521,7 +2507,7 @@ void remove_thread(struct thread_entry *thread) | |||
2521 | /* Thread being killed - become a waiter */ | 2507 | /* Thread being killed - become a waiter */ |
2522 | UNLOCK_THREAD(thread); | 2508 | UNLOCK_THREAD(thread); |
2523 | corelock_unlock(&thread->waiter_cl); | 2509 | corelock_unlock(&thread->waiter_cl); |
2524 | set_irq_level(oldlevel); | 2510 | restore_irq(oldlevel); |
2525 | thread_wait(thread); | 2511 | thread_wait(thread); |
2526 | return; | 2512 | return; |
2527 | } | 2513 | } |
@@ -2543,11 +2529,11 @@ void remove_thread(struct thread_entry *thread) | |||
2543 | corelock_unlock(&thread->waiter_cl); | 2529 | corelock_unlock(&thread->waiter_cl); |
2544 | 2530 | ||
2545 | UNLOCK_THREAD(thread); | 2531 | UNLOCK_THREAD(thread); |
2546 | set_irq_level(oldlevel); | 2532 | restore_irq(oldlevel); |
2547 | 2533 | ||
2548 | old_core = switch_core(new_core); | 2534 | old_core = switch_core(new_core); |
2549 | 2535 | ||
2550 | oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 2536 | oldlevel = disable_irq_save(); |
2551 | 2537 | ||
2552 | corelock_lock(&thread->waiter_cl); | 2538 | corelock_lock(&thread->waiter_cl); |
2553 | LOCK_THREAD(thread); | 2539 | LOCK_THREAD(thread); |
@@ -2643,7 +2629,7 @@ thread_killed: /* Thread was already killed */ | |||
2643 | /* Removal complete - safe to unlock and reenable interrupts */ | 2629 | /* Removal complete - safe to unlock and reenable interrupts */ |
2644 | corelock_unlock(&thread->waiter_cl); | 2630 | corelock_unlock(&thread->waiter_cl); |
2645 | UNLOCK_THREAD(thread); | 2631 | UNLOCK_THREAD(thread); |
2646 | set_irq_level(oldlevel); | 2632 | restore_irq(oldlevel); |
2647 | 2633 | ||
2648 | #if NUM_CORES > 1 | 2634 | #if NUM_CORES > 1 |
2649 | if (old_core < NUM_CORES) | 2635 | if (old_core < NUM_CORES) |
@@ -2675,7 +2661,7 @@ int thread_set_priority(struct thread_entry *thread, int priority) | |||
2675 | 2661 | ||
2676 | /* Thread could be on any list and therefore on an interrupt accessible | 2662 | /* Thread could be on any list and therefore on an interrupt accessible |
2677 | one - disable interrupts */ | 2663 | one - disable interrupts */ |
2678 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 2664 | int oldlevel = disable_irq_save(); |
2679 | 2665 | ||
2680 | LOCK_THREAD(thread); | 2666 | LOCK_THREAD(thread); |
2681 | 2667 | ||
@@ -2788,7 +2774,7 @@ int thread_set_priority(struct thread_entry *thread, int priority) | |||
2788 | 2774 | ||
2789 | UNLOCK_THREAD(thread); | 2775 | UNLOCK_THREAD(thread); |
2790 | 2776 | ||
2791 | set_irq_level(oldlevel); | 2777 | restore_irq(oldlevel); |
2792 | 2778 | ||
2793 | return old_base_priority; | 2779 | return old_base_priority; |
2794 | } | 2780 | } |
@@ -2815,14 +2801,14 @@ int thread_get_priority(struct thread_entry *thread) | |||
2815 | */ | 2801 | */ |
2816 | void thread_thaw(struct thread_entry *thread) | 2802 | void thread_thaw(struct thread_entry *thread) |
2817 | { | 2803 | { |
2818 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 2804 | int oldlevel = disable_irq_save(); |
2819 | LOCK_THREAD(thread); | 2805 | LOCK_THREAD(thread); |
2820 | 2806 | ||
2821 | if (thread->state == STATE_FROZEN) | 2807 | if (thread->state == STATE_FROZEN) |
2822 | core_schedule_wakeup(thread); | 2808 | core_schedule_wakeup(thread); |
2823 | 2809 | ||
2824 | UNLOCK_THREAD(thread); | 2810 | UNLOCK_THREAD(thread); |
2825 | set_irq_level(oldlevel); | 2811 | restore_irq(oldlevel); |
2826 | } | 2812 | } |
2827 | 2813 | ||
2828 | /*--------------------------------------------------------------------------- | 2814 | /*--------------------------------------------------------------------------- |
@@ -2850,14 +2836,14 @@ unsigned int switch_core(unsigned int new_core) | |||
2850 | return core; | 2836 | return core; |
2851 | } | 2837 | } |
2852 | 2838 | ||
2853 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | 2839 | int oldlevel = disable_irq_save(); |
2854 | LOCK_THREAD(current); | 2840 | LOCK_THREAD(current); |
2855 | 2841 | ||
2856 | if (current->name == THREAD_DESTRUCT) | 2842 | if (current->name == THREAD_DESTRUCT) |
2857 | { | 2843 | { |
2858 | /* Thread being killed - deactivate and let process complete */ | 2844 | /* Thread being killed - deactivate and let process complete */ |
2859 | UNLOCK_THREAD(current); | 2845 | UNLOCK_THREAD(current); |
2860 | set_irq_level(oldlevel); | 2846 | restore_irq(oldlevel); |
2861 | thread_wait(current); | 2847 | thread_wait(current); |
2862 | /* Should never be reached */ | 2848 | /* Should never be reached */ |
2863 | THREAD_PANICF("switch_core->D:*R", current); | 2849 | THREAD_PANICF("switch_core->D:*R", current); |