Page MenuHomeFreeBSD

D14330.id39560.diff
No OneTemporary

D14330.id39560.diff

Index: sys/conf/files.powerpc
===================================================================
--- sys/conf/files.powerpc
+++ sys/conf/files.powerpc
@@ -120,6 +120,7 @@
powerpc/aim/moea64_native.c optional aim
powerpc/aim/mp_cpudep.c optional aim
powerpc/aim/slb.c optional aim powerpc64
+powerpc/aim/cpu_subr64.S optional aim powerpc64
powerpc/booke/locore.S optional booke no-obj
powerpc/booke/booke_machdep.c optional booke
powerpc/booke/machdep_e500.c optional booke_e500
Index: sys/powerpc/aim/cpu_subr64.S
===================================================================
--- /dev/null
+++ sys/powerpc/aim/cpu_subr64.S
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2017-2018 QCM Technologies.
+ * Copyright (c) 2017-2018 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "assym.s"
+
+#include <machine/asm.h>
+
+ .globl CNAME(power_save_sequence)
+ .p2align 3
+ENTRY(enter_idle_powerx)
+ mfsprg0 %r3 /* Get the pcpu pointer */
+ ld %r3,PC_CURTHREAD(%r3) /* Get current thread */
+ ld %r3,TD_PCB(%r3) /* Get PCB of current thread */
+ std %r12,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs. */
+ std %r13,PCB_CONTEXT+1*8(%r3)
+ std %r14,PCB_CONTEXT+2*8(%r3)
+ std %r15,PCB_CONTEXT+3*8(%r3)
+ std %r16,PCB_CONTEXT+4*8(%r3)
+ std %r17,PCB_CONTEXT+5*8(%r3)
+ std %r18,PCB_CONTEXT+6*8(%r3)
+ std %r19,PCB_CONTEXT+7*8(%r3)
+ std %r20,PCB_CONTEXT+8*8(%r3)
+ std %r21,PCB_CONTEXT+9*8(%r3)
+ std %r22,PCB_CONTEXT+10*8(%r3)
+ std %r23,PCB_CONTEXT+11*8(%r3)
+ std %r24,PCB_CONTEXT+12*8(%r3)
+ std %r25,PCB_CONTEXT+13*8(%r3)
+ std %r26,PCB_CONTEXT+14*8(%r3)
+ std %r27,PCB_CONTEXT+15*8(%r3)
+ std %r28,PCB_CONTEXT+16*8(%r3)
+ std %r29,PCB_CONTEXT+17*8(%r3)
+ std %r30,PCB_CONTEXT+18*8(%r3)
+ std %r31,PCB_CONTEXT+19*8(%r3)
+
+ mfcr %r16 /* Save the condition register */
+ std %r16,PCB_CR(%r3)
+ mflr %r16 /* Save the link register */
+ std %r16,PCB_LR(%r3)
+ std %r1,PCB_SP(%r3) /* Save the stack pointer */
+ std %r2,PCB_TOC(%r3) /* Save the TOC pointer */
+
+ /* Set where we want to jump */
+ bl 1f
+ .llong power_save_sequence /* Remember about 8 byte alignment */
+1: mflr %r3
+ ld %r3,0(%r3)
+ mtsrr0 %r3
+
+ /* Set MSR */
+ li %r3,0
+ ori %r3,%r3,(PSL_ME | PSL_RI)
+ li %r8,0x9 /* PSL_SF and PSL_HV */
+ insrdi %r3,%r8,4,0
+ mtsrr1 %r3
+
+ rfid
+
+ .p2align 2
+CNAME(power_save_sequence):
+ bl 1f
+ .llong 0x0 /* Playground for power-save sequence */
+1: mflr %r3
+
+ /* Start power-save sequence */
+ std %r2,0(%r3)
+ ptesync
+ ld %r2,0(%r3)
+2: cmpd %r2,%r2
+ bne 2b
+ nap
+ b .
Index: sys/powerpc/aim/locore64.S
===================================================================
--- sys/powerpc/aim/locore64.S
+++ sys/powerpc/aim/locore64.S
@@ -96,6 +96,10 @@
/* Released */
or 2,2,2 /* unyield */
+
+ /* Make sure that it will be software reset. Clear SRR1 */
+ li %r1,0
+ mtsrr1 %r1
ba EXC_RST
Index: sys/powerpc/aim/mp_cpudep.c
===================================================================
--- sys/powerpc/aim/mp_cpudep.c
+++ sys/powerpc/aim/mp_cpudep.c
@@ -398,8 +398,11 @@
case IBMPOWER8:
case IBMPOWER8E:
#ifdef __powerpc64__
- if (mfmsr() & PSL_HV)
- mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_LPES);
+ if (mfmsr() & PSL_HV) {
+ mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_LPES |
+ LPCR_PECE_WAKESET);
+ isync();
+ }
#endif
break;
default:
Index: sys/powerpc/aim/trap_subr64.S
===================================================================
--- sys/powerpc/aim/trap_subr64.S
+++ sys/powerpc/aim/trap_subr64.S
@@ -307,10 +307,24 @@
* once the MMU is turned on.
*/
.globl CNAME(rstcode), CNAME(rstcodeend), CNAME(cpu_reset_handler)
+ .globl CNAME(cpu_wakeup_handler)
.p2align 3
CNAME(rstcode):
+ /*
+ * Check if this is software reset or
+ * processor is waking up from power saving mode
+ * It is software reset when 46:47 = 0b00
+ */
+ mfsrr1 %r9 /* Load SRR1 into r9 */
+ andis. %r9,%r9,0x3 /* Logic AND with 46:47 bits */
+ beq 2f /* Branch if software reset */
+ bl 1f
+ .llong cpu_wakeup_handler
+
+ /* It is software reset */
+
/* Explicitly set MSR[SF] */
- mfmsr %r9
+2: mfmsr %r9
li %r8,1
insrdi %r9,%r8,1,0
mtmsrd %r9
@@ -318,6 +332,7 @@
bl 1f
.llong cpu_reset_handler /* Make sure to maintain 8-byte alignment */
+
1: mflr %r9
ld %r9,0(%r9)
mtlr %r9
@@ -359,6 +374,51 @@
9:
b 9b
+cpu_wakeup_handler:
+ /* Turn on MMU after return from interrupt */
+ mfsrr1 %r3
+ ori %r3,%r3,(PSL_IR | PSL_DR)
+ mtsrr1 %r3
+
+ /* Turn on MMU (needed to access PCB) */
+ mfmsr %r3
+ ori %r3,%r3,(PSL_IR | PSL_DR)
+ mtmsr %r3
+ isync
+
+ mfsprg0 %r3
+
+ ld %r3,PC_CURTHREAD(%r3) /* Get current thread */
+ ld %r3,TD_PCB(%r3) /* Get PCB of current thread */
+ ld %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs. */
+ ld %r13,PCB_CONTEXT+1*8(%r3)
+ ld %r14,PCB_CONTEXT+2*8(%r3)
+ ld %r15,PCB_CONTEXT+3*8(%r3)
+ ld %r16,PCB_CONTEXT+4*8(%r3)
+ ld %r17,PCB_CONTEXT+5*8(%r3)
+ ld %r18,PCB_CONTEXT+6*8(%r3)
+ ld %r19,PCB_CONTEXT+7*8(%r3)
+ ld %r20,PCB_CONTEXT+8*8(%r3)
+ ld %r21,PCB_CONTEXT+9*8(%r3)
+ ld %r22,PCB_CONTEXT+10*8(%r3)
+ ld %r23,PCB_CONTEXT+11*8(%r3)
+ ld %r24,PCB_CONTEXT+12*8(%r3)
+ ld %r25,PCB_CONTEXT+13*8(%r3)
+ ld %r26,PCB_CONTEXT+14*8(%r3)
+ ld %r27,PCB_CONTEXT+15*8(%r3)
+ ld %r28,PCB_CONTEXT+16*8(%r3)
+ ld %r29,PCB_CONTEXT+17*8(%r3)
+ ld %r30,PCB_CONTEXT+18*8(%r3)
+ ld %r31,PCB_CONTEXT+19*8(%r3)
+ ld %r5,PCB_CR(%r3) /* Load the condition register */
+ mtcr %r5
+ ld %r5,PCB_LR(%r3) /* Load the link register */
+ mtsrr0 %r5
+ ld %r1,PCB_SP(%r3) /* Load the stack pointer */
+ ld %r2,PCB_TOC(%r3) /* Load the TOC pointer */
+
+ rfid
+
/*
* This code gets copied to all the trap vectors
* (except ISI/DSI, ALI, and the interrupts). Has to fit in 8 instructions!
Index: sys/powerpc/include/cpu.h
===================================================================
--- sys/powerpc/include/cpu.h
+++ sys/powerpc/include/cpu.h
@@ -112,6 +112,8 @@
extern char btext[];
extern char etext[];
+extern void enter_idle_powerx(void);
+
void cpu_halt(void);
void cpu_reset(void);
void cpu_sleep(void);
Index: sys/powerpc/include/spr.h
===================================================================
--- sys/powerpc/include/spr.h
+++ sys/powerpc/include/spr.h
@@ -201,6 +201,13 @@
#define SPR_LPCR 0x13e /* Logical Partitioning Control */
#define LPCR_LPES 0x008 /* Bit 60 */
+#define LPCR_PECE_DRBL (1ULL << 16) /* Directed Privileged Doorbell */
+#define LPCR_PECE_HDRBL (1ULL << 15) /* Directed Hypervisor Doorbell */
+#define LPCR_PECE_EXT (1ULL << 14) /* External exceptions */
+#define LPCR_PECE_DECR (1ULL << 13) /* Decrementer exceptions */
+#define LPCR_PECE_ME (1ULL << 12) /* Machine Check and Hypervisor */
+ /* Maintenance exceptions */
+#define LPCR_PECE_WAKESET (LPCR_PECE_EXT | LPCR_PECE_DECR | LPCR_PECE_ME)
#define SPR_EPCR 0x133
#define EPCR_EXTGS 0x80000000
Index: sys/powerpc/powernv/platform_powernv.c
===================================================================
--- sys/powerpc/powernv/platform_powernv.c
+++ sys/powerpc/powernv/platform_powernv.c
@@ -139,7 +139,9 @@
opal_call(OPAL_REINIT_CPUS, 1 /* Big endian */);
#endif
+ if (cpu_idle_hook == NULL)
cpu_idle_hook = powernv_cpu_idle;
+
powernv_boot_pir = mfspr(SPR_PIR);
/* LPID must not be altered when PSL_DR or PSL_IR is set */
@@ -150,11 +152,11 @@
mtspr(SPR_LPID, 0);
isync();
- mtmsr(msr);
-
mtspr(SPR_LPCR, LPCR_LPES);
isync();
+ mtmsr(msr);
+
/* Init CPU bits */
powernv_smp_ap_init(plat);
Index: sys/powerpc/powerpc/cpu.c
===================================================================
--- sys/powerpc/powerpc/cpu.c
+++ sys/powerpc/powerpc/cpu.c
@@ -68,6 +68,7 @@
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
+#include <sys/sched.h>
#include <machine/bus.h>
#include <machine/cpu.h>
@@ -81,11 +82,13 @@
static void cpu_6xx_setup(int cpuid, uint16_t vers);
static void cpu_970_setup(int cpuid, uint16_t vers);
static void cpu_booke_setup(int cpuid, uint16_t vers);
+static void cpu_powerx_setup(int cpuid, uint16_t vers);
int powerpc_pow_enabled;
void (*cpu_idle_hook)(sbintime_t) = NULL;
static void cpu_idle_60x(sbintime_t);
static void cpu_idle_booke(sbintime_t);
+static void cpu_idle_powerx(sbintime_t);
struct cputab {
const char *name;
@@ -156,13 +159,13 @@
PPC_FEATURE_SMT | PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_ARCH_2_06 |
PPC_FEATURE_HAS_VSX,
PPC_FEATURE2_ARCH_2_07 | PPC_FEATURE2_HAS_HTM | PPC_FEATURE2_ISEL |
- PPC_FEATURE2_HAS_VCRYPTO, NULL },
+ PPC_FEATURE2_HAS_VCRYPTO, cpu_powerx_setup },
{ "IBM POWER8", IBMPOWER8, REVFMT_MAJMIN,
PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU |
PPC_FEATURE_SMT | PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_ARCH_2_06 |
PPC_FEATURE_HAS_VSX,
PPC_FEATURE2_ARCH_2_07 | PPC_FEATURE2_HAS_HTM | PPC_FEATURE2_ISEL |
- PPC_FEATURE2_HAS_VCRYPTO, NULL },
+ PPC_FEATURE2_HAS_VCRYPTO, cpu_powerx_setup },
{ "IBM POWER9", IBMPOWER9, REVFMT_MAJMIN,
PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU |
PPC_FEATURE_SMT | PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_ARCH_2_06 |
@@ -610,6 +613,27 @@
cpu_idle_hook = cpu_idle_60x;
}
+static void
+cpu_powerx_setup(int cpuid, uint16_t vers)
+{
+
+ if ((mfmsr() & PSL_HV) == 0)
+ return;
+
+ /* Configure power-saving */
+ switch (vers) {
+ case IBMPOWER8:
+ case IBMPOWER8E:
+ mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_PECE_WAKESET);
+ isync();
+ break;
+ default:
+ return;
+ }
+
+ cpu_idle_hook = cpu_idle_powerx;
+}
+
static int
cpu_feature_bit(SYSCTL_HANDLER_ARGS)
{
@@ -696,3 +720,16 @@
#endif
}
+static void
+cpu_idle_powerx(sbintime_t sbt)
+{
+
+ spinlock_enter();
+ if (sched_runnable()) {
+ spinlock_exit();
+ return;
+ }
+
+ enter_idle_powerx();
+ spinlock_exit();
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 19, 9:49 PM (16 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23943402
Default Alt Text
D14330.id39560.diff (10 KB)

Event Timeline