powerpc/64s: Expand core idle state bits
authorNicholas Piggin <npiggin@gmail.com>
Wed, 19 Apr 2017 13:05:48 +0000 (23:05 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 23 Apr 2017 10:31:49 +0000 (20:31 +1000)
In preparation for adding more bits to the core idle state word, move
the lock bit up, and unlock by flipping the lock bit rather than masking
off all but the thread bits.

Add branch hints for atomic operations while we're here.

Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/cpuidle.h
arch/powerpc/kernel/idle_book3s.S

index 4649ca0d28e3c8bde9fe7f29900aa7f55f0a91e7..dd6a63f0a10fc20538bd1a7a7adbb85153344ec6 100644 (file)
@@ -7,8 +7,8 @@
 #define PNV_THREAD_NAP                  1
 #define PNV_THREAD_SLEEP                2
 #define PNV_THREAD_WINKLE               3
-#define PNV_CORE_IDLE_LOCK_BIT          0x100
-#define PNV_CORE_IDLE_THREAD_BITS       0x0FF
+#define PNV_CORE_IDLE_LOCK_BIT          0x10000000
+#define PNV_CORE_IDLE_THREAD_BITS       0x000000FF
 
 /*
  * ============================ NOTE =================================
index 4e5a4fed86c5aafde6d48ac8f0bf353ec5657427..335d15bfb945a31f5a4e4868d2359d18cc98c8d4 100644 (file)
@@ -95,12 +95,12 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
 core_idle_lock_held:
        HMT_LOW
 3:     lwz     r15,0(r14)
-       andi.   r15,r15,PNV_CORE_IDLE_LOCK_BIT
+       andis.  r15,r15,PNV_CORE_IDLE_LOCK_BIT@h
        bne     3b
        HMT_MEDIUM
        lwarx   r15,0,r14
-       andi.   r9,r15,PNV_CORE_IDLE_LOCK_BIT
-       bne     core_idle_lock_held
+       andis.  r9,r15,PNV_CORE_IDLE_LOCK_BIT@h
+       bne-    core_idle_lock_held
        blr
 
 /*
@@ -213,8 +213,8 @@ pnv_enter_arch207_idle_mode:
 lwarx_loop1:
        lwarx   r15,0,r14
 
-       andi.   r9,r15,PNV_CORE_IDLE_LOCK_BIT
-       bnel    core_idle_lock_held
+       andis.  r9,r15,PNV_CORE_IDLE_LOCK_BIT@h
+       bnel-   core_idle_lock_held
 
        andc    r15,r15,r7                      /* Clear thread bit */
 
@@ -241,7 +241,7 @@ common_enter: /* common code for all the threads entering sleep or winkle */
        IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
 
 fastsleep_workaround_at_entry:
-       ori     r15,r15,PNV_CORE_IDLE_LOCK_BIT
+       oris    r15,r15,PNV_CORE_IDLE_LOCK_BIT@h
        stwcx.  r15,0,r14
        bne-    lwarx_loop1
        isync
@@ -251,10 +251,10 @@ fastsleep_workaround_at_entry:
        li      r4,1
        bl      opal_config_cpu_idle_state
 
-       /* Clear Lock bit */
-       li      r0,0
+       /* Unlock */
+       xoris   r15,r15,PNV_CORE_IDLE_LOCK_BIT@h
        lwsync
-       stw     r0,0(r14)
+       stw     r15,0(r14)
        b       common_enter
 
 enter_winkle:
@@ -302,8 +302,8 @@ power_enter_stop:
 
 lwarx_loop_stop:
        lwarx   r15,0,r14
-       andi.   r9,r15,PNV_CORE_IDLE_LOCK_BIT
-       bnel    core_idle_lock_held
+       andis.  r9,r15,PNV_CORE_IDLE_LOCK_BIT@h
+       bnel-   core_idle_lock_held
        andc    r15,r15,r7                      /* Clear thread bit */
 
        stwcx.  r15,0,r14
@@ -560,7 +560,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
        ld      r14,PACA_CORE_IDLE_STATE_PTR(r13)
 lwarx_loop2:
        lwarx   r15,0,r14
-       andi.   r9,r15,PNV_CORE_IDLE_LOCK_BIT
+       andis.  r9,r15,PNV_CORE_IDLE_LOCK_BIT@h
        /*
         * Lock bit is set in one of the 2 cases-
         * a. In the sleep/winkle enter path, the last thread is executing
@@ -569,9 +569,10 @@ lwarx_loop2:
         * workaround undo code or resyncing timebase or restoring context
         * In either case loop until the lock bit is cleared.
         */
-       bnel    core_idle_lock_held
+       bnel-   core_idle_lock_held
 
-       cmpwi   cr2,r15,0
+       andi.   r9,r15,PNV_CORE_IDLE_THREAD_BITS
+       cmpwi   cr2,r9,0
 
        /*
         * At this stage
@@ -580,7 +581,7 @@ lwarx_loop2:
         * cr4 - gt or eq if waking up from complete hypervisor state loss.
         */
 
-       ori     r15,r15,PNV_CORE_IDLE_LOCK_BIT
+       oris    r15,r15,PNV_CORE_IDLE_LOCK_BIT@h
        stwcx.  r15,0,r14
        bne-    lwarx_loop2
        isync
@@ -670,7 +671,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        mtspr   SPRN_WORC,r4
 
 clear_lock:
-       andi.   r15,r15,PNV_CORE_IDLE_THREAD_BITS
+       xoris   r15,r15,PNV_CORE_IDLE_LOCK_BIT@h
        lwsync
        stw     r15,0(r14)