From nobody Fri Nov 11 19:50:39 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4N88Sw1Vthz4fpMn; Fri, 11 Nov 2022 19:50:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4N88Sw13ytz4GbD; Fri, 11 Nov 2022 19:50:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1668196240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=f4YUaN5NtaJE/CnAUA5zsVUEoE3jTn+gptABmQ4cobA=; b=LqA57107190RF7GeYl/dSr/jCP6j4CyDkG7oSdrT0TNHAineIN77edR79W1lf57plabwWe LC1ZwRD3IuuD2wtMZNm+B724m2oz9kjr4RwhxUFnwzxqMuC0sWSCtx6Vg8vtrZTwtaNkm9 DwH4N+qhs5cTlyfNPJauQFw7zLtdzX3BmVw8yLDIm1kwJSz+6JnmmEpvonXsMXr44/952x 5jrvWWVCORynlzIwnKklrRroZRBR9dEy2FGx8VJOg8BUSsuEMV1uJ3fkZmfLX4fskAztFj 3GW66MKoJ5BSyqcPsZ0wrANKXpZ7ku09j2R3cFe7BUo4lRpQbemcYs48PpLR4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1668196240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=f4YUaN5NtaJE/CnAUA5zsVUEoE3jTn+gptABmQ4cobA=; b=PTyjSE/5YamInNVK/H+pBXb07b1OtAHChb4WJ5Xfyde5mCFIW0u7I24nEmAp0z67gr/3DF mB5GuRm9VBnaarlk09lB2iTgN8RPYHBG5Zt5aZN8oEVsZR2xijJbSeyvY+2z8aNU3wyOVz HaBZ93yfVdCRPY8uFk2rzdPpFj2u+SDaSx7zqfil9iJvBNK7s12mWHyWpDpFvEDM7zAqi+ RUCNvQSwlyUDuf+EJs9jkOuq5bIYnB2oyCqRxOlA1MXC+J428GfEyR57h2ck0PPfla6uOw yT9Ny8kWgnXXrsJ5JgRPc1vgFLJmHZANuIkUB0qkPSmMT4bRb94DDEcov3WhVQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1668196240; a=rsa-sha256; cv=none; b=ST0JKaahhBjBSTDZ4k9HLi2yyd4FR8Am8vM0nhbRehSS+2G/OkR9nwNZEB49k2SW9P1N+k ePjMyzomilFE3i6N5S/AJ0PtpJQGbWgRLapthjRI4pWEbuSQDex/DxEjFAd+aFKhPk+4Lu 2+NcVDQ+Wokk/jDXXbh+imLPkoA7Ax9X7/2EDsqsdQ4YN3z0H3vBELIXDEZ2ufKU+F91eW ZHdWrobz3VtmZqKS5ZQJBdybFIl91k1MYgBKJG5gXNBB37t/vKtS/nw6Q1SDRHqaPKO+CL UCTwnZDeW7D4UUcvczwREv4DEhf8lxtbE3E52SrWz+9l2ts+n4M9HH2tQgxR1A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4N88Sw06bQzv2G; Fri, 11 Nov 2022 19:50:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2ABJod7R013226; Fri, 11 Nov 2022 19:50:39 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2ABJodsv013225; Fri, 11 Nov 2022 19:50:39 GMT (envelope-from git) Date: Fri, 11 Nov 2022 19:50:39 GMT Message-Id: <202211111950.2ABJodsv013225@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: 753a23ac152c - main - arm64: add a spin-table implementation for Apple Silicon List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 753a23ac152c5024de34f9eb02a2fdccf2881085 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=753a23ac152c5024de34f9eb02a2fdccf2881085 commit 753a23ac152c5024de34f9eb02a2fdccf2881085 Author: Kyle Evans AuthorDate: 2022-11-11 19:50:29 +0000 Commit: Kyle Evans CommitDate: 2022-11-11 19:50:29 +0000 arm64: add a spin-table implementation for Apple Silicon The M1 has no EL3, so we're limited to a spin-table implementation if we want to eventually use bhyve on it. Implement spin-table now, but note that we still prefer PSCI where possible. Reviewed by: mmel Differential Revision: https://reviews.freebsd.org/D34661 --- sys/arm64/arm64/mp_machdep.c | 113 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 14 deletions(-) diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index ef0ded31bcf7..4276b6dcffd2 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -489,12 +489,54 @@ cpu_mp_probe(void) return (1); } +static int +enable_cpu_psci(uint64_t target_cpu, vm_paddr_t entry, u_int cpuid) +{ + int err; + + err = psci_cpu_on(target_cpu, entry, cpuid); + if (err != PSCI_RETVAL_SUCCESS) { + /* + * Panic here if INVARIANTS are enabled and PSCI failed to + * start the requested CPU. psci_cpu_on() returns PSCI_MISSING + * to indicate we are unable to use it to start the given CPU. + */ + KASSERT(err == PSCI_MISSING || + (mp_quirks & MP_QUIRK_CPULIST) == MP_QUIRK_CPULIST, + ("Failed to start CPU %u (%lx), error %d\n", + cpuid, target_cpu, err)); + return (EINVAL); + } + + return (0); +} + +static int +enable_cpu_spin(uint64_t cpu, vm_paddr_t entry, vm_paddr_t release_paddr) +{ + vm_paddr_t *release_addr; + + release_addr = pmap_mapdev(release_paddr, sizeof(*release_addr)); + if (release_addr == NULL) + return (ENOMEM); + + *release_addr = entry; + pmap_unmapdev(release_addr, sizeof(*release_addr)); + + __asm __volatile( + "dsb sy \n" + "sev \n" + ::: "memory"); + + return (0); +} + /* * Starts a given CPU. If the CPU is already running, i.e. it is the boot CPU, * do nothing. Returns true if the CPU is present and running. */ static bool -start_cpu(u_int cpuid, uint64_t target_cpu, int domain) +start_cpu(u_int cpuid, uint64_t target_cpu, int domain, vm_paddr_t release_addr) { struct pcpu *pcpup; vm_size_t size; @@ -530,18 +572,19 @@ start_cpu(u_int cpuid, uint64_t target_cpu, int domain) printf("Starting CPU %u (%lx)\n", cpuid, target_cpu); pa = pmap_extract(kernel_pmap, (vm_offset_t)mpentry); - err = psci_cpu_on(target_cpu, pa, cpuid); - if (err != PSCI_RETVAL_SUCCESS) { - /* - * Panic here if INVARIANTS are enabled and PSCI failed to - * start the requested CPU. psci_cpu_on() returns PSCI_MISSING - * to indicate we are unable to use it to start the given CPU. - */ - KASSERT(err == PSCI_MISSING || - (mp_quirks & MP_QUIRK_CPULIST) == MP_QUIRK_CPULIST, - ("Failed to start CPU %u (%lx), error %d\n", - cpuid, target_cpu, err)); + /* + * A limited set of hardware we support can only do spintables and + * remain useful, due to lack of EL3. Thus, we'll usually fall into the + * PSCI branch here. + */ + MPASS(release_addr == 0 || !psci_present); + if (release_addr != 0) + err = enable_cpu_spin(target_cpu, pa, release_addr); + else + err = enable_cpu_psci(target_cpu, pa, cpuid); + + if (err != 0) { pcpu_destroy(pcpup); dpcpu[cpuid - 1] = NULL; kmem_free(bootstacks[cpuid], MP_BOOTSTACK_SIZE); @@ -583,7 +626,7 @@ madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) if (vm_ndomains > 1) domain = acpi_pxm_get_cpu_locality(intr->Uid); #endif - if (start_cpu(id, intr->ArmMpidr, domain)) { + if (start_cpu(id, intr->ArmMpidr, domain, 0)) { MPASS(cpuid_to_pcpu[id] != NULL); cpuid_to_pcpu[id]->pc_acpi_id = intr->Uid; /* @@ -630,10 +673,27 @@ cpu_init_acpi(void) #endif #ifdef FDT +/* + * Failure is indicated by failing to populate *release_addr. + */ +static void +populate_release_addr(phandle_t node, vm_paddr_t *release_addr) +{ + pcell_t buf[2]; + + if (OF_getencprop(node, "cpu-release-addr", buf, sizeof(buf)) != + sizeof(buf)) + return; + + *release_addr = (((uintptr_t)buf[0] << 32) | buf[1]); +} + static boolean_t start_cpu_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg) { uint64_t target_cpu; + vm_paddr_t release_addr; + char *enable_method; int domain; int cpuid; @@ -648,7 +708,32 @@ start_cpu_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg) else cpuid = fdt_cpuid; - if (!start_cpu(cpuid, target_cpu, 0)) + /* + * If PSCI is present, we'll always use that -- the cpu_on method is + * mandated in both v0.1 and v0.2. We'll check the enable-method if + * we don't have PSCI and use spin table if it's provided. + */ + release_addr = 0; + if (!psci_present && cpuid != 0) { + if (OF_getprop_alloc(node, "enable-method", + (void **)&enable_method) <= 0) + return (FALSE); + + if (strcmp(enable_method, "spin-table") != 0) { + OF_prop_free(enable_method); + return (FALSE); + } + + OF_prop_free(enable_method); + populate_release_addr(node, &release_addr); + if (release_addr == 0) { + printf("Failed to fetch release address for CPU %u", + cpuid); + return (FALSE); + } + } + + if (!start_cpu(cpuid, target_cpu, 0, release_addr)) return (FALSE); /*