From owner-svn-src-all@freebsd.org Thu Apr 12 17:43:21 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2E401F8116A; Thu, 12 Apr 2018 17:43:21 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id C88BA824C9; Thu, 12 Apr 2018 17:43:20 +0000 (UTC) (envelope-from br@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AAFAC689A; Thu, 12 Apr 2018 17:43:20 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3CHhKoh050021; Thu, 12 Apr 2018 17:43:20 GMT (envelope-from br@FreeBSD.org) Received: (from br@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3CHhJnu050013; Thu, 12 Apr 2018 17:43:19 GMT (envelope-from br@FreeBSD.org) Message-Id: <201804121743.w3CHhJnu050013@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: br set sender to br@FreeBSD.org using -f From: Ruslan Bukin Date: Thu, 12 Apr 2018 17:43:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332441 - in head/sys: conf mips/beri mips/include mips/mips X-SVN-Group: head X-SVN-Commit-Author: br X-SVN-Commit-Paths: in head/sys: conf mips/beri mips/include mips/mips X-SVN-Commit-Revision: 332441 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Apr 2018 17:43:21 -0000 Author: br Date: Thu Apr 12 17:43:19 2018 New Revision: 332441 URL: https://svnweb.freebsd.org/changeset/base/332441 Log: Add SMP support for BERI CPU. Obtained from: CheriBSD Sponsored by: DARPA, AFRL Added: head/sys/mips/beri/beri_mp.c (contents, props changed) head/sys/mips/beri/beri_mp.h (contents, props changed) Modified: head/sys/conf/options.mips head/sys/mips/beri/files.beri head/sys/mips/beri/std.beri head/sys/mips/include/cpufunc.h head/sys/mips/include/hwfunc.h head/sys/mips/mips/mp_machdep.c Modified: head/sys/conf/options.mips ============================================================================== --- head/sys/conf/options.mips Thu Apr 12 17:16:13 2018 (r332440) +++ head/sys/conf/options.mips Thu Apr 12 17:43:19 2018 (r332441) @@ -99,6 +99,7 @@ OCTEON_BOARD_CAPK_0100ND opt_cvmx.h # Options specific to the BERI platform. # BERI_LARGE_TLB opt_global.h +PLATFORM_INIT_SECONDARY opt_global.h # # Options that control the NetFPGA-10G Embedded CPU Ethernet Core. Added: head/sys/mips/beri/beri_mp.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/beri/beri_mp.c Thu Apr 12 17:43:19 2018 (r332441) @@ -0,0 +1,309 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * Copyright (c) 2012-2015 Robert N. M. Watson + * Copyright (c) 2013 SRI International + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +#include + +#include + +struct spin_entry { + uint64_t entry_addr; + uint64_t a0; + uint32_t rsvd1; + uint32_t pir; + uint64_t rsvd2; +}; + +static phandle_t cpu_of_nodes[MAXCPU]; +static device_t picmap[MAXCPU]; + +int +platform_processor_id(void) +{ + int cpu; + + cpu = beri_get_cpu(); + + return (cpu); +} + +void +platform_cpu_mask(cpuset_t *mask) +{ + int ncores, ncpus, nthreads; + phandle_t cpus, cpu; + pcell_t reg; + char prop[16]; + struct spin_entry *se; + + ncores = beri_get_ncores(); + nthreads = beri_get_nthreads(); + KASSERT(ncores <= 0x10000, ("%s: too many cores %d", __func__, ncores)); + KASSERT(nthreads <= 0x10000, ("%s: too many threads %d", __func__, + nthreads)); + KASSERT(ncores < 0xffff || nthreads < 0xffff, + ("%s: cores x thread (%d x %d) would overflow", __func__, ncores, + nthreads)); + ncpus = ncores * nthreads; + if (MAXCPU > 1 && ncpus > MAXCPU) + printf("%s: Hardware supports more CPUs (%d) than kernel (%d)\n", + __func__, ncpus, MAXCPU); + printf("%s: hardware has %d cores with %d threads each\n", __func__, + ncores, nthreads); + + if ((cpus = OF_finddevice("/cpus")) <= 0) { + printf("%s: no \"/cpus\" device found in FDT\n", __func__); + goto error; + } + if ((cpu = OF_child(cpus)) <= 0) { + printf("%s: no children of \"/cpus\" found in FDT\n", __func__); + goto error; + } + CPU_ZERO(mask); + do { + if (OF_getprop(cpu, "reg", ®, sizeof(reg)) <= 0) { + printf("%s: cpu device with no reg property\n", + __func__); + goto error; + } + if (reg > MAXCPU) { + printf("%s: cpu ID too large (%d > %d)\n", __func__, + reg, MAXCPU); + continue; + } + cpu_of_nodes[reg] = cpu; + + if (reg != 0) { + if (OF_getprop(cpu, "enable-method", &prop, + sizeof(prop)) <= 0 && OF_getprop(OF_parent(cpu), + "enable-method", &prop, sizeof(prop)) <= 0) { + printf("%s: CPU %d has no enable-method " + "property\n", __func__, reg); + continue; + } + if (strcmp("spin-table", prop) != 0) { + printf("%s: CPU %d enable-method is '%s' not " + "'spin-table'\n", __func__, reg, prop); + continue; + } + + if (OF_getprop(cpu, "cpu-release-addr", &se, + sizeof(se)) <= 0) { + printf("%s: CPU %d has missing or invalid " + "cpu-release-addr\n", __func__, reg); + continue; + } + if (se->entry_addr != 1) { + printf("%s: CPU %d has uninitalized spin " + "entry\n", __func__, reg); + continue; + } + } + + CPU_SET(reg, mask); + } while ((cpu = OF_peer(cpu)) > 0); + return; + +error: + /* + * If we run into any problems determining the CPU layout, + * fall back to UP. + * + * XXX: panic instead? + */ + CPU_ZERO(mask); + CPU_SET(0, mask); +} + +void +platform_init_secondary(int cpuid) +{ + device_t ic; + int ipi; + + ipi = platform_ipi_hardintr_num(); + + ic = devclass_get_device(devclass_find("beripic"), cpuid); + picmap[cpuid] = ic; + beripic_setup_ipi(ic, cpuid, ipi); + + /* Unmask the interrupt */ + if (cpuid != 0) { + mips_wr_status(mips_rd_status() | (((1 << ipi) << 8) << 2)); + } +} + + +void +platform_ipi_send(int cpuid) +{ + + mips_sync(); /* Ordering, liveness. */ + + beripic_send_ipi(picmap[cpuid], cpuid); +} + +void +platform_ipi_clear(void) +{ + int cpuid; + + cpuid = platform_processor_id(); + + beripic_clear_ipi(picmap[cpuid], cpuid); +} + +/* + * XXXBED: Set via FDT? + */ +int +platform_ipi_hardintr_num(void) +{ + + return (4); +} + +int +platform_ipi_softintr_num(void) +{ + + return (-1); +} + +/* + * XXXBED: Fine for MT, will need something better for multi-core. + */ +struct cpu_group * +platform_smp_topo(void) +{ + + return (smp_topo_none()); +} + +void +platform_init_ap(int cpuid) +{ + uint32_t status; + u_int clock_int_mask; + + KASSERT(cpuid < MAXCPU, ("%s: invalid CPU id %d", __func__, cpuid)); + + /* Make sure coprocessors are enabled. */ + status = mips_rd_status(); + status |= (MIPS_SR_COP_0_BIT | MIPS_SR_COP_1_BIT); +#if defined(CPU_CHERI) + status |= MIPS_SR_COP_2_BIT; +#endif + mips_wr_status(status); + +#if 0 + register_t hwrena; + /* Enable HDWRD instruction in userspace. Also enables statcounters. */ + hwrena = mips_rd_hwrena(); + hwrena |= (MIPS_HWRENA_CC | MIPS_HWRENA_CCRES | MIPS_HWRENA_CPUNUM | + MIPS_HWRENA_BERI_STATCOUNTERS_MASK); + mips_wr_hwrena(hwrena); +#endif + + /* + * Enable per-thread timer. + */ + clock_int_mask = hard_int_mask(5); + set_intr_mask(clock_int_mask); +} + +/* + * BERI startup conforms to the spin-table start method defined in the + * ePAPR 1.0 spec. The initial spin waiting for an address is started + * by the CPU firmware. + */ +int +platform_start_ap(int cpuid) +{ + phandle_t cpu; + char prop[16]; + struct spin_entry *se; + + KASSERT(cpuid != 0, ("%s: can't start CPU 0!\n", __func__)); + KASSERT((cpuid > 0 && cpuid < MAXCPU), + ("%s: invalid CPU id %d", __func__, cpuid)); + + cpu = cpu_of_nodes[cpuid]; + if (OF_getprop(cpu, "status", &prop, sizeof(prop)) <= 0) { + if (bootverbose) + printf("%s: CPU %d has no status property, " + "trying parent\n", __func__, cpuid); + if (OF_getprop(OF_parent(cpu), "status", &prop, + sizeof(prop)) <= 0) + panic("%s: CPU %d has no status property", __func__, + cpuid); + } + if (strcmp("disabled", prop) != 0) + panic("%s: CPU %d status is '%s' not 'disabled'", + __func__, cpuid, prop); + + if (OF_getprop(cpu, "enable-method", &prop, sizeof(prop)) <= 0) { + if (bootverbose) + printf("%s: CPU %d has no enable-method, " + "trying parent\n", __func__, cpuid); + if (OF_getprop(OF_parent(cpu), "enable-method", &prop, + sizeof(prop)) <= 0) + panic("%s: CPU %d has no enable-method property", + __func__, cpuid); + } + if (strcmp("spin-table", prop) != 0) + panic("%s: CPU %d enable-method is '%s' not " + "'spin-table'", __func__, cpuid, prop); + + if (OF_getprop(cpu, "cpu-release-addr", &se, sizeof(se)) <= 0) + panic("%s: CPU %d has missing or invalid cpu-release-addr", + __func__, cpuid); + se->pir = cpuid; + if (bootverbose) + printf("%s: writing %p to %p\n", __func__, mpentry, + &se->entry_addr); + + mips_sync(); /* Ordering. */ + se->entry_addr = (intptr_t)mpentry; + mips_sync(); /* Liveness. */ + + return (0); +} Added: head/sys/mips/beri/beri_mp.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/beri/beri_mp.h Thu Apr 12 17:43:19 2018 (r332441) @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2014 SRI International + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-11-C-0249) + * ("MRC2"), as part of the DARPA MRC research programme. + * + * 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. + * + * $FreeBSD$ + */ + +static inline int +beri_get_core(void) +{ + uint32_t cinfo; + + cinfo = mips_rd_cinfo(); + return (cinfo & 0xffff); +} + +static inline int +beri_get_ncores(void) +{ + uint32_t cinfo; + + cinfo = mips_rd_cinfo(); + return ((cinfo >> 16) + 1); +} + +static inline int +beri_get_thread(void) +{ + uint32_t tinfo; + + tinfo = mips_rd_tinfo(); + return (tinfo & 0xffff); +} + +static inline int +beri_get_nthreads(void) +{ + uint32_t tinfo; + + tinfo = mips_rd_tinfo(); + return ((tinfo >> 16) + 1); +} + +static inline int +beri_get_cpu(void) +{ + + return ((beri_get_core() * beri_get_nthreads()) + beri_get_thread()); +} + +static inline int +beri_get_ncpus(void) +{ + + return(beri_get_ncores() * beri_get_nthreads()); +} + +void beripic_setup_ipi(device_t dev, u_int tid, u_int ipi_irq); +void beripic_send_ipi(device_t dev, u_int tid); +void beripic_clear_ipi(device_t dev, u_int tid); Modified: head/sys/mips/beri/files.beri ============================================================================== --- head/sys/mips/beri/files.beri Thu Apr 12 17:16:13 2018 (r332440) +++ head/sys/mips/beri/files.beri Thu Apr 12 17:43:19 2018 (r332441) @@ -21,5 +21,6 @@ dev/terasic/mtl/terasic_mtl_syscons.c optional terasic dev/terasic/mtl/terasic_mtl_text.c optional terasic_mtl dev/terasic/mtl/terasic_mtl_vt.c optional terasic_mtl vt mips/beri/beri_machdep.c standard +mips/beri/beri_mp.c optional smp mips/beri/beri_pic.c optional fdt mips/mips/tick.c standard Modified: head/sys/mips/beri/std.beri ============================================================================== --- head/sys/mips/beri/std.beri Thu Apr 12 17:16:13 2018 (r332440) +++ head/sys/mips/beri/std.beri Thu Apr 12 17:43:19 2018 (r332441) @@ -4,3 +4,4 @@ files "../beri/files.beri" cpu CPU_MIPS4KC options BERI_LARGE_TLB +options PLATFORM_INIT_SECONDARY Modified: head/sys/mips/include/cpufunc.h ============================================================================== --- head/sys/mips/include/cpufunc.h Thu Apr 12 17:16:13 2018 (r332440) +++ head/sys/mips/include/cpufunc.h Thu Apr 12 17:43:19 2018 (r332441) @@ -279,6 +279,8 @@ MIPS_RW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0); MIPS_RW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1); #endif MIPS_RW32_COP0(prid, MIPS_COP_0_PRID); +MIPS_RW32_COP0_SEL(cinfo, MIPS_COP_0_PRID, 6); +MIPS_RW32_COP0_SEL(tinfo, MIPS_COP_0_PRID, 7); /* XXX 64-bit? */ MIPS_RW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1); Modified: head/sys/mips/include/hwfunc.h ============================================================================== --- head/sys/mips/include/hwfunc.h Thu Apr 12 17:16:13 2018 (r332440) +++ head/sys/mips/include/hwfunc.h Thu Apr 12 17:43:19 2018 (r332441) @@ -72,6 +72,13 @@ void platform_init_ap(int processor_id); int platform_ipi_hardintr_num(void); int platform_ipi_softintr_num(void); +#ifdef PLATFORM_INIT_SECONDARY +/* + * Set up IPIs for this CPU. + */ +void platform_init_secondary(int cpuid); +#endif + /* * Trigger a IPI interrupt on 'cpuid'. */ Modified: head/sys/mips/mips/mp_machdep.c ============================================================================== --- head/sys/mips/mips/mp_machdep.c Thu Apr 12 17:16:13 2018 (r332440) +++ head/sys/mips/mips/mp_machdep.c Thu Apr 12 17:43:19 2018 (r332441) @@ -304,6 +304,10 @@ smp_init_secondary(u_int32_t cpuid) while (!aps_ready) ; +#ifdef PLATFORM_INIT_SECONDARY + platform_init_secondary(cpuid); +#endif + /* Initialize curthread. */ KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread")); PCPU_SET(curthread, PCPU_GET(idlethread)); @@ -343,6 +347,10 @@ release_aps(void *dummy __unused) if (mp_ncpus == 1) return; + +#ifdef PLATFORM_INIT_SECONDARY + platform_init_secondary(0); +#endif /* * IPI handler