From owner-svn-src-all@freebsd.org Thu Nov 19 09:26:51 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id F0C4D2ECD1F; Thu, 19 Nov 2020 09:26:51 +0000 (UTC) (envelope-from andrew@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 "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CcDpM6WRfz4R78; Thu, 19 Nov 2020 09:26:51 +0000 (UTC) (envelope-from andrew@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 D27992194F; Thu, 19 Nov 2020 09:26:51 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AJ9Qp70016791; Thu, 19 Nov 2020 09:26:51 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AJ9QpNi016790; Thu, 19 Nov 2020 09:26:51 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <202011190926.0AJ9QpNi016790@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Thu, 19 Nov 2020 09:26:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367841 - head/sys/arm64/arm64 X-SVN-Group: head X-SVN-Commit-Author: andrew X-SVN-Commit-Paths: head/sys/arm64/arm64 X-SVN-Commit-Revision: 367841 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.34 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, 19 Nov 2020 09:26:52 -0000 Author: andrew Date: Thu Nov 19 09:26:51 2020 New Revision: 367841 URL: https://svnweb.freebsd.org/changeset/base/367841 Log: Fall back to use the GICR address from the generic interrupt struct When there is no ACPI redistributor sub-table in the MADT we need to fall back to use the GICR base address from the GIC CPU interface structure. Handle this fallback when adding memory to the device and when counting the number of redistributors. PR: 251171 Reported by: Andrey Fesenko Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D27247 Modified: head/sys/arm64/arm64/gic_v3_acpi.c Modified: head/sys/arm64/arm64/gic_v3_acpi.c ============================================================================== --- head/sys/arm64/arm64/gic_v3_acpi.c Thu Nov 19 09:17:41 2020 (r367840) +++ head/sys/arm64/arm64/gic_v3_acpi.c Thu Nov 19 09:26:51 2020 (r367841) @@ -88,6 +88,7 @@ struct madt_table_data { device_t dev; ACPI_MADT_GENERIC_DISTRIBUTOR *dist; int count; + bool rdist_use_gicc; }; static void @@ -120,12 +121,16 @@ static void rdist_map(ACPI_SUBTABLE_HEADER *entry, void *arg) { ACPI_MADT_GENERIC_REDISTRIBUTOR *redist; + ACPI_MADT_GENERIC_INTERRUPT *intr; struct madt_table_data *madt_data; + rman_res_t count; madt_data = (struct madt_table_data *)arg; switch(entry->Type) { case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: + if (madt_data->rdist_use_gicc) + break; redist = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)entry; madt_data->count++; @@ -134,6 +139,23 @@ rdist_map(ACPI_SUBTABLE_HEADER *entry, void *arg) redist->Length); break; + case ACPI_MADT_TYPE_GENERIC_INTERRUPT: + if (!madt_data->rdist_use_gicc) + break; + + intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry; + + madt_data->count++; + /* + * Map the two 64k redistributor frames. + */ + count = GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE; + if (madt_data->dist->Version == ACPI_MADT_GIC_VERSION_V4) + count += GICR_VLPI_BASE_SIZE + GICR_RESERVED_SIZE; + BUS_SET_RESOURCE(madt_data->parent, madt_data->dev, + SYS_RES_MEMORY, madt_data->count, intr->GicrBaseAddress, + count); + default: break; } @@ -190,8 +212,18 @@ gic_v3_acpi_identify(driver_t *driver, device_t parent madt_data.dist->BaseAddress, 128 * 1024); madt_data.dev = dev; + madt_data.rdist_use_gicc = false; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, rdist_map, &madt_data); + if (madt_data.count == 0) { + /* + * No redistributors found, fall back to use the GICR + * address from the GICC sub-table. + */ + madt_data.rdist_use_gicc = true; + acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, + rdist_map, &madt_data); + } acpi_set_private(dev, (void *)(uintptr_t)madt_data.dist->Version); @@ -224,6 +256,15 @@ madt_count_redistrib(ACPI_SUBTABLE_HEADER *entry, void sc->gic_redists.nregions++; } +static void +madt_count_gicc_redistrib(ACPI_SUBTABLE_HEADER *entry, void *arg) +{ + struct gic_v3_softc *sc = arg; + + if (entry->Type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) + sc->gic_redists.nregions++; +} + static int gic_v3_acpi_count_regions(device_t dev) { @@ -245,6 +286,12 @@ gic_v3_acpi_count_regions(device_t dev) acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_count_redistrib, sc); + /* Fall back to use the distributor GICR base address */ + if (sc->gic_redists.nregions == 0) { + acpi_walk_subtables(madt + 1, + (char *)madt + madt->Header.Length, + madt_count_gicc_redistrib, sc); + } acpi_unmap_table(madt); return (sc->gic_redists.nregions > 0 ? 0 : ENXIO);