From patchwork Thu Jun 22 16:22:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 779614 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wtn6z3zZGz9s9Y for ; Fri, 23 Jun 2017 02:27:39 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wtn6z2fMrzDr9l for ; Fri, 23 Jun 2017 02:27:39 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3wtn5m3pcnzDr7D for ; Fri, 23 Jun 2017 02:26:36 +1000 (AEST) Received: from pasglop.austin.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id v5MGMaCh024844; Thu, 22 Jun 2017 11:26:03 -0500 From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Thu, 22 Jun 2017 11:22:24 -0500 Message-Id: <20170622162225.26344-23-benh@kernel.crashing.org> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170622162225.26344-1-benh@kernel.crashing.org> References: <20170622162225.26344-1-benh@kernel.crashing.org> Subject: [Skiboot] [PATCH 23/24] cpu: Rework HILE change X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Create a more generic helper for changing HID0 bits on all processors. Signed-off-by: Benjamin Herrenschmidt --- core/cpu.c | 71 +++++++++++++++++++++++++++++++++--------------------- core/fast-reboot.c | 5 ++-- include/cpu.h | 3 ++- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/core/cpu.c b/core/cpu.c index a083ed7..31f5c92 100644 --- a/core/cpu.c +++ b/core/cpu.c @@ -52,6 +52,7 @@ static bool hile_supported; static unsigned long hid0_hile; static unsigned long hid0_attn; static bool pm_enabled; +static bool current_hile_mode; unsigned long cpu_secondary_start __force_data = 0; @@ -1024,44 +1025,51 @@ static int64_t opal_return_cpu(void) } opal_call(OPAL_RETURN_CPU, opal_return_cpu, 0); -static void cpu_change_hile(void *hilep) -{ - bool hile = *(bool *)hilep; - unsigned long hid0; - - hid0 = mfspr(SPR_HID0); - if (hile) - hid0 |= hid0_hile; - else - hid0 &= ~hid0_hile; - prlog(PR_DEBUG, "CPU: [%08x] HID0 set to 0x%016lx\n", - this_cpu()->pir, hid0); - set_hid0(hid0); +struct hid0_change_req { + uint64_t clr_bits; + uint64_t set_bits; +}; - this_cpu()->current_hile = hile; +static void cpu_change_hid0(void *__req) +{ + struct hid0_change_req *req = __req; + unsigned long hid0, new_hid0; + + hid0 = new_hid0 = mfspr(SPR_HID0); + new_hid0 &= ~req->clr_bits; + new_hid0 |= req->set_bits; + prlog(PR_DEBUG, "CPU: [%08x] HID0 change 0x%016lx -> 0x%016lx\n", + this_cpu()->pir, hid0, new_hid0); + set_hid0(new_hid0); } -static int64_t cpu_change_all_hile(bool hile) +static int64_t cpu_change_all_hid0(struct hid0_change_req *req) { struct cpu_thread *cpu; - prlog(PR_INFO, "CPU: Switching HILE on all CPUs to %d\n", hile); - for_each_available_cpu(cpu) { - if (cpu->current_hile == hile) + if (!cpu_is_thread0(cpu)) continue; if (cpu == this_cpu()) { - cpu_change_hile(&hile); + cpu_change_hid0(req); continue; } - cpu_wait_job(cpu_queue_job(cpu, "cpu_change_hile", - cpu_change_hile, &hile), true); + cpu_wait_job(cpu_queue_job(cpu, "cpu_change_hid0", + cpu_change_hid0, req), true); } return OPAL_SUCCESS; } +void cpu_fast_reboot_complete(void) +{ + /* Fast reboot will have cleared HID0:HILE */ + current_hile_mode = false; + +} + static int64_t opal_reinit_cpus(uint64_t flags) { + struct hid0_change_req req = { 0, 0 }; struct cpu_thread *cpu; int64_t rc = OPAL_SUCCESS; int i; @@ -1105,19 +1113,26 @@ static int64_t opal_reinit_cpus(uint64_t flags) this_cpu()->in_reinit = true; unlock(&reinit_lock); - /* - * If the flags affect endianness and we are on P8 DD2 or later, then - * use the HID bit. We use the PVR (we could use the EC level in - * the chip but the PVR is more readily available). - */ + /* If HILE change via HID0 is supported ... */ if (hile_supported && - (flags & (OPAL_REINIT_CPUS_HILE_BE | OPAL_REINIT_CPUS_HILE_LE))) { + (flags & (OPAL_REINIT_CPUS_HILE_BE | + OPAL_REINIT_CPUS_HILE_LE))) { bool hile = !!(flags & OPAL_REINIT_CPUS_HILE_LE); flags &= ~(OPAL_REINIT_CPUS_HILE_BE | OPAL_REINIT_CPUS_HILE_LE); - rc = cpu_change_all_hile(hile); + if (hile != current_hile_mode) { + if (hile) + req.set_bits |= hid0_hile; + else + req.clr_bits |= hid0_hile; + current_hile_mode = hile; + } } + /* Apply HID bits changes if any */ + if (req.set_bits || req.clr_bits) + cpu_change_all_hid0(&req); + /* If we have a P7, error out for LE switch, do nothing for BE */ if (proc_gen < proc_gen_p8) { if (flags & OPAL_REINIT_CPUS_HILE_LE) diff --git a/core/fast-reboot.c b/core/fast-reboot.c index 884441d..7bfc06d 100644 --- a/core/fast-reboot.c +++ b/core/fast-reboot.c @@ -370,8 +370,6 @@ static void cleanup_cpu_state(void) { struct cpu_thread *cpu = this_cpu(); - cpu->current_hile = false; - /* Per core cleanup */ if (cpu_is_thread0(cpu)) { /* Shared SPRs whacked back to normal */ @@ -562,6 +560,9 @@ void __noreturn fast_reboot_entry(void) /* Set our state to active */ this_cpu()->state = cpu_state_active; + /* Let the CPU layer do some last minute global cleanups */ + cpu_fast_reboot_complete(); + /* We can now do NAP mode */ cpu_set_pm_enable(true); diff --git a/include/cpu.h b/include/cpu.h index 0cb6389..1d19c20 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -48,7 +48,6 @@ struct cpu_thread { uint32_t server_no; uint32_t chip_id; bool is_secondary; - bool current_hile; struct cpu_thread *primary; enum cpu_thread_state state; struct dt_node *node; @@ -271,4 +270,6 @@ extern unsigned long __attrconst cpu_stack_top(unsigned int pir); extern void cpu_idle_job(void); extern void cpu_idle_delay(unsigned long delay, unsigned long min_pm); +extern void cpu_fast_reboot_complete(void); + #endif /* __CPU_H */