summaryrefslogtreecommitdiff
path: root/firmware/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/thread.c')
-rw-r--r--firmware/thread.c82
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
405static inline void core_sleep(unsigned int core) 405static 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)
775static inline void core_sleep(void) 765static 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)
781static inline void core_sleep(void) 771static 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
794static inline void core_sleep(void) 782static 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
806static inline void core_sleep(void) 792static 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)
2212static struct thread_entry * find_empty_thread_slot(void) 2198static 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)
2247void core_idle(void) 2233void 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(&current->waiter_cl); 2409 corelock_lock(&current->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 */
2816void thread_thaw(struct thread_entry *thread) 2802void 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);