From owner-svn-src-stable@freebsd.org Fri Dec 23 03:08:28 2016 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6F64BC8C1BD; Fri, 23 Dec 2016 03:08:28 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 31CF218FE; Fri, 23 Dec 2016 03:08:28 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBN38RME090893; Fri, 23 Dec 2016 03:08:27 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBN38ROT090891; Fri, 23 Dec 2016 03:08:27 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201612230308.uBN38ROT090891@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits Date: Fri, 23 Dec 2016 03:08:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r310440 - in stable/11/sys/powerpc: booke mpc85xx X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Dec 2016 03:08:28 -0000 Author: jhibbits Date: Fri Dec 23 03:08:27 2016 New Revision: 310440 URL: https://svnweb.freebsd.org/changeset/base/310440 Log: MFC r304047,r304068: r304047: Add ePAPR boot support for PowerPC book-E (MPC85xx) hardware r304068: Only flush bp_kernload from the dcache, no need to sync the icache on the boot CPU. Modified: stable/11/sys/powerpc/booke/locore.S stable/11/sys/powerpc/mpc85xx/platform_mpc85xx.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/powerpc/booke/locore.S ============================================================================== --- stable/11/sys/powerpc/booke/locore.S Fri Dec 23 03:07:19 2016 (r310439) +++ stable/11/sys/powerpc/booke/locore.S Fri Dec 23 03:08:27 2016 (r310440) @@ -409,6 +409,8 @@ bp_kernload: ori %r3, %r3, (MAS3_SX | MAS3_SW | MAS3_SR)@l mtspr SPR_MAS3, %r3 isync + bl zero_mas7 + bl zero_mas8 tlbwe isync msync Modified: stable/11/sys/powerpc/mpc85xx/platform_mpc85xx.c ============================================================================== --- stable/11/sys/powerpc/mpc85xx/platform_mpc85xx.c Fri Dec 23 03:07:19 2016 (r310439) +++ stable/11/sys/powerpc/mpc85xx/platform_mpc85xx.c Fri Dec 23 03:08:27 2016 (r310440) @@ -39,7 +39,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -53,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include @@ -63,6 +66,15 @@ extern void *ap_pcpu; extern vm_paddr_t kernload; /* Kernel physical load address */ extern uint8_t __boot_page[]; /* Boot page body */ extern uint32_t bp_kernload; + +struct cpu_release { + uint32_t entry_h; + uint32_t entry_l; + uint32_t r3_h; + uint32_t r3_l; + uint32_t reserved; + uint32_t pir; +}; #endif extern uint32_t *bootinfo; @@ -316,6 +328,51 @@ mpc85xx_smp_get_bsp(platform_t plat, str return (0); } +#ifdef SMP +static int +mpc85xx_smp_start_cpu_epapr(platform_t plat, struct pcpu *pc) +{ + vm_paddr_t rel_pa, bptr; + volatile struct cpu_release *rel; + vm_offset_t rel_va, rel_page; + phandle_t node; + int i; + + /* If we're calling this, the node already exists. */ + node = OF_finddevice("/cpus"); + for (i = 0, node = OF_child(node); i < pc->pc_cpuid; + i++, node = OF_peer(node)) + ; + if (OF_getencprop(node, "cpu-release-addr", (pcell_t *)&rel_pa, + sizeof(rel_pa)) == -1) { + return (ENOENT); + } + + rel_page = kva_alloc(PAGE_SIZE); + if (rel_page == 0) + return (ENOMEM); + + critical_enter(); + rel_va = rel_page + (rel_pa & PAGE_MASK); + pmap_kenter(rel_page, rel_pa & ~PAGE_MASK); + rel = (struct cpu_release *)rel_va; + bptr = ((vm_paddr_t)(uintptr_t)__boot_page - KERNBASE) + kernload; + cpu_flush_dcache(__DEVOLATILE(struct cpu_release *,rel), sizeof(*rel)); + rel->pir = pc->pc_cpuid; __asm __volatile("sync"); + rel->entry_h = (bptr >> 32); + rel->entry_l = bptr; __asm __volatile("sync"); + cpu_flush_dcache(__DEVOLATILE(struct cpu_release *,rel), sizeof(*rel)); + if (bootverbose) + printf("Waking up CPU %d via CPU release page %p\n", + pc->pc_cpuid, rel); + critical_exit(); + pmap_kremove(rel_page); + kva_free(rel_page, PAGE_SIZE); + + return (0); +} +#endif + static int mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc) { @@ -325,6 +382,7 @@ mpc85xx_smp_start_cpu(platform_t plat, s int timeout; uintptr_t brr; int cpuid; + int epapr_boot = 0; uint32_t tgt; if (mpc85xx_is_qoriq()) { @@ -342,6 +400,20 @@ mpc85xx_smp_start_cpu(platform_t plat, s cpuid = pc->pc_cpuid + 24; } bp_kernload = kernload; + /* + * bp_kernload is in the boot page. Sync the cache because ePAPR + * booting has the other core(s) already running. + */ + cpu_flush_dcache(&bp_kernload, sizeof(bp_kernload)); + + ap_pcpu = pc; + __asm __volatile("msync; isync"); + + /* First try the ePAPR way. */ + if (mpc85xx_smp_start_cpu_epapr(plat, pc) == 0) { + epapr_boot = 1; + goto spin_wait; + } reg = ccsr_read4(brr); if ((reg & (1 << cpuid)) != 0) { @@ -350,9 +422,6 @@ mpc85xx_smp_start_cpu(platform_t plat, s return (ENXIO); } - ap_pcpu = pc; - __asm __volatile("msync; isync"); - /* Flush caches to have our changes hit DRAM. */ cpu_flush_dcache(__boot_page, 4096); @@ -413,6 +482,7 @@ mpc85xx_smp_start_cpu(platform_t plat, s ccsr_write4(brr, reg | (1 << cpuid)); __asm __volatile("isync; msync"); +spin_wait: timeout = 500; while (!pc->pc_awake && timeout--) DELAY(1000); /* wait 1ms */ @@ -422,11 +492,13 @@ mpc85xx_smp_start_cpu(platform_t plat, s * address (= 0xfffff000) isn't permanently remapped and thus not * usable otherwise. */ - if (mpc85xx_is_qoriq()) - ccsr_write4(OCP85XX_BSTAR, 0); - else - ccsr_write4(OCP85XX_BPTR, 0); - __asm __volatile("isync; msync"); + if (!epapr_boot) { + if (mpc85xx_is_qoriq()) + ccsr_write4(OCP85XX_BSTAR, 0); + else + ccsr_write4(OCP85XX_BPTR, 0); + __asm __volatile("isync; msync"); + } if (!pc->pc_awake) panic("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid);