From owner-hackers+M88963=david=gwynne.id.au@openbsd.org Mon Jun 10 06:41:30 2019 Delivered-To: david@gwynne.id.au Received: by 2002:a17:906:6284:0:0:0:0 with SMTP id t4csp1573374ejk; Sun, 9 Jun 2019 13:41:30 -0700 (PDT) X-Google-Smtp-Source: APXvYqydBrzDNkVcRA1usoR8/r2ynn/tvRX/7VgAfuyXrGpbmSCHlYAh0lizk3rFN/6dV4SsVDYj X-Received: by 2002:a25:943:: with SMTP id u3mr31852371ybm.293.1560112890676; Sun, 09 Jun 2019 13:41:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560112890; cv=none; d=google.com; s=arc-20160816; b=ApMFHgJHo/Xca9IqYfowv4RZNN4VqRvR9sEVjv2RnRNrs8DSJ4QnFuq7S9hyMfDi6M URuC9dRE66nINtFFC+YRk1ZHMNKWeTtPvD0oCpMbHAiqS0jfocB55YT1obcFe++10gzL y+7HNDmHI65HmdhycpB4RUBXIZpSiyhEn4g02cfee8MFo1Ne84fYY6viKhBDIvMk9ow4 zg2ekI7iSnRsJr0rjMKUskkwKgVhPggDGCFSTyzZhUYNGzHBuLW7+/eOFBWhiE3O2ThX wiDWKle0qjpbOXOF1Q09TobI1mjK3GstuROWRFJhiJyWQQKlahukjTJOzLcQdEAd5Y0i V/0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:precedence:list-unsubscribe:list-subscribe:list-post :list-owner:list-id:list-help:message-id:subject:to:from:date; bh=AxQKifCIoE2XViQfZZrHJe0QlQKthsKEhM70V/aeX20=; b=UhTETrW5AwkF4IhDGULBQ5vIEyzo7UibnS4/WctBn0uMCLlHIJ3jAAPxbaHvjWoBiS 0NoMp++Qi4xxo9lwNenDTu7lwu6lnEmi6o21D4Hb1EbTbo6in4nuaP7wFp3bMcxeOWCy 33lNgXfOU/GjHlwJMbKOfRYEP5D5qkMytY0+qvvQGY1i5MD+4s4a4ehKkWL3ipRosLXN MCQMqfkE8CMMmszWcg0jHC0UjvtH4X9J4obezZrQ3lrY9MmZ9F+Xkykh+rEg1KrVIcww 5KpX7aO3+EVFxI23I/ODbP1t0FsOBahxJe/mzMftVGyRn+qd/W28EV/6sGjj5pooo7QE 8LIQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of owner-hackers+m88963=david=gwynne.id.au@openbsd.org designates 199.185.178.25 as permitted sender) smtp.mailfrom="owner-hackers+M88963=david=gwynne.id.au@openbsd.org" Return-Path: Received: from mail.openbsd.org (mail.openbsd.org. [199.185.178.25]) by mx.google.com with ESMTPS id m9si2614175ybp.435.2019.06.09.13.41.30 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 09 Jun 2019 13:41:30 -0700 (PDT) Received-SPF: pass (google.com: domain of owner-hackers+m88963=david=gwynne.id.au@openbsd.org designates 199.185.178.25 as permitted sender) client-ip=199.185.178.25; Authentication-Results: mx.google.com; spf=pass (google.com: domain of owner-hackers+m88963=david=gwynne.id.au@openbsd.org designates 199.185.178.25 as permitted sender) smtp.mailfrom="owner-hackers+M88963=david=gwynne.id.au@openbsd.org" Received: from openbsd.org (localhost [127.0.0.1]) by mail.openbsd.org (OpenSMTPD) with ESMTP id 1afe71be for ; Sun, 9 Jun 2019 14:41:27 -0600 (MDT) Received: from sibelius.xs4all.nl (sibelius.xs4all.nl [83.163.83.176]) by mail.openbsd.org (OpenSMTPD) with ESMTPS id d6c86e19 (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256:NO) for ; Sun, 9 Jun 2019 14:41:22 -0600 (MDT) Received: from localhost (bloch.sibelius.xs4all.nl [local]) by bloch.sibelius.xs4all.nl (OpenSMTPD) with ESMTPA id 2549eca9 for ; Sun, 9 Jun 2019 22:41:19 +0200 (CEST) Date: Sun, 9 Jun 2019 22:41:19 +0200 (CEST) From: Mark Kettenis To: hackers@openbsd.org Subject: acpipci(4) diff Message-ID: <54385fab007d0d0b@bloch.sibelius.xs4all.nl> List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Loop: hackers@openbsd.org Precedence: list Sender: owner-hackers@openbsd.org Status: RO Content-Length: 9801 Lines: 350 A recent bug report from jmatthew@ and dlg@ made me look once more at using ACPI information to attach PCI busses. Here is a first attempt that extends acpipci(4) and attaches pci(4) to it like we already do on arm64. At this point, I'm interested in getting this tested on a wide variety of hardware. I'm especially interested in older stuff and server machines. Please send me a dmesg and the contents of /var/db/acpi and let me know if something breaks or doesn't show up anymore. Index: arch/amd64/amd64/mainbus.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v retrieving revision 1.47 diff -u -p -r1.47 mainbus.c --- arch/amd64/amd64/mainbus.c 17 May 2019 19:07:15 -0000 1.47 +++ arch/amd64/amd64/mainbus.c 9 Jun 2019 20:30:19 -0000 @@ -231,6 +231,9 @@ mainbus_attach(struct device *parent, st #endif #if NPCI > 0 +#if NACPI > 0 + if (!acpi_haspci) +#endif { pci_init_extents(); Index: arch/amd64/conf/GENERIC =================================================================== RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v retrieving revision 1.473 diff -u -p -r1.473 GENERIC --- arch/amd64/conf/GENERIC 7 Jun 2019 16:06:59 -0000 1.473 +++ arch/amd64/conf/GENERIC 9 Jun 2019 20:30:19 -0000 @@ -48,6 +48,7 @@ acpicmos* at acpi? acpidock* at acpi? acpiec* at acpi? acpipci* at acpi? +pci* at acpipci? acpiprt* at acpi? acpisbs* at acpi? acpitz* at acpi? Index: arch/amd64/conf/files.amd64 =================================================================== RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v retrieving revision 1.102 diff -u -p -r1.102 files.amd64 --- arch/amd64/conf/files.amd64 17 May 2019 19:07:16 -0000 1.102 +++ arch/amd64/conf/files.amd64 9 Jun 2019 20:30:19 -0000 @@ -237,7 +237,7 @@ attach acpi at bios file arch/amd64/amd64/acpi_machdep.c acpi file arch/amd64/amd64/acpi_wakecode.S acpi & !small_kernel -device acpipci +device acpipci: pcibus attach acpipci at acpi file arch/amd64/pci/acpipci.c acpipci Index: arch/amd64/pci/acpipci.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/pci/acpipci.c,v retrieving revision 1.1 diff -u -p -r1.1 acpipci.c --- arch/amd64/pci/acpipci.c 26 Oct 2018 20:26:19 -0000 1.1 +++ arch/amd64/pci/acpipci.c 9 Jun 2019 20:30:19 -0000 @@ -53,6 +53,19 @@ struct acpipci_softc { struct device sc_dev; struct acpi_softc *sc_acpi; struct aml_node *sc_node; + + bus_space_tag_t sc_iot; + bus_space_tag_t sc_memt; + bus_dma_tag_t sc_dmat; + + struct extent *sc_busex; + struct extent *sc_memex; + struct extent *sc_ioex; + char sc_busex_name[32]; + char sc_ioex_name[32]; + char sc_memex_name[32]; + int sc_bus; + uint32_t sc_seg; }; int acpipci_match(struct device *, void *, void *); @@ -72,6 +85,11 @@ const char *acpipci_hids[] = { NULL }; +void acpipci_attach_deferred(struct device *); +int acpipci_print(void *, const char *); +int acpipci_parse_resources(int, union acpi_resource *, void *); +void acpipci_osc(struct acpipci_softc *); + int acpipci_match(struct device *parent, void *match, void *aux) { @@ -86,15 +104,163 @@ acpipci_attach(struct device *parent, st { struct acpi_attach_args *aaa = aux; struct acpipci_softc *sc = (struct acpipci_softc *)self; - struct aml_value args[4]; struct aml_value res; - static uint8_t uuid[16] = ACPI_PCI_UUID; - uint32_t buf[3]; + uint64_t bbn = 0; + uint64_t seg = 0; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_node = aaa->aaa_node; printf(" %s", sc->sc_node->name); + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) { + printf(": can't find resources\n"); + return; + } + + aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn); + sc->sc_bus = bbn; + + aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg); + sc->sc_seg = seg; + + /* Create extents for our address spaces. */ + snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name), + "%s pcibus", sc->sc_dev.dv_xname); + snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), + "%s pciio", sc->sc_dev.dv_xname); + snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), + "%s pcimem", sc->sc_dev.dv_xname); + sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255, + M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); + sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff, + M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); + sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1, + M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); + + aml_parse_resource(&res, acpipci_parse_resources, sc); + + acpipci_osc(sc); + + printf("\n"); + + extent_print(sc->sc_busex); + extent_print(sc->sc_ioex); + extent_print(sc->sc_memex); + + acpi_haspci = 1; + + sc->sc_iot = aaa->aaa_iot; + sc->sc_memt = aaa->aaa_memt; + sc->sc_dmat = aaa->aaa_dmat; + + config_defer(self, acpipci_attach_deferred); +} + +void +acpipci_attach_deferred(struct device *self) +{ + struct acpipci_softc *sc = (struct acpipci_softc *)self; + struct pcibus_attach_args pba; + + memset(&pba, 0, sizeof(pba)); + pba.pba_busname = "pci"; + pba.pba_iot = sc->sc_iot; + pba.pba_memt = sc->sc_memt; + pba.pba_dmat = sc->sc_dmat; + pba.pba_busex = sc->sc_busex; + pba.pba_ioex = sc->sc_ioex; + pba.pba_memex = sc->sc_memex; + pba.pba_pmemex = sc->sc_memex; + pba.pba_domain = pci_ndomains++; + pba.pba_bus = sc->sc_bus; + pba.pba_flags |= PCI_FLAGS_MSI_ENABLED; + + config_found(self, &pba, acpipci_print); +} + +int +acpipci_print(void *aux, const char *pnp) +{ + struct pcibus_attach_args *pba = aux; + + if (pnp) + printf("%s at %s", pba->pba_busname, pnp); + printf(" bus %d", pba->pba_bus); + return (UNCONF); +} + +int +acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg) +{ + struct acpipci_softc *sc = arg; + int type = AML_CRSTYPE(crs); + int restype, tflags = 0; + u_long min, len = 0, tra = 0; + + switch (type) { + case LR_WORD: + restype = crs->lr_word.type; + tflags = crs->lr_word.tflags; + min = crs->lr_word._min; + len = crs->lr_word._len; + tra = crs->lr_word._tra; + break; + case LR_DWORD: + restype = crs->lr_dword.type; + tflags = crs->lr_dword.tflags; + min = crs->lr_dword._min; + len = crs->lr_dword._len; + tra = crs->lr_dword._tra; + break; + case LR_QWORD: + restype = crs->lr_qword.type; + tflags = crs->lr_qword.tflags; + min = crs->lr_qword._min; + len = crs->lr_qword._len; + tra = crs->lr_qword._tra; + break; + case LR_MEM32FIXED: + /* + * Coreboot on the PC Engines apu2 incorrectly uses a + * Memory32Fixed resource descriptor to describe mmio + * address space forwarded to the PCI bus. + */ + restype = LR_TYPE_MEMORY; + min = crs->lr_m32fixed._bas; + len = crs->lr_m32fixed._len; + break; + } + + if (len == 0) + return 0; + + switch (restype) { + case LR_TYPE_MEMORY: + if (tflags & LR_MEMORY_TTP) + return 0; + extent_free(sc->sc_memex, min, len, EX_WAITOK | EX_CONFLICTOK); + break; + case LR_TYPE_IO: + if (tflags & LR_IO_TTP) + return 0; + extent_free(sc->sc_ioex, min, len, EX_WAITOK | EX_CONFLICTOK); + break; + case LR_TYPE_BUS: + extent_free(sc->sc_busex, min, len, EX_WAITOK); + break; + } + + return 0; +} + +void +acpipci_osc(struct acpipci_softc *sc) +{ + struct aml_value args[4]; + struct aml_value res; + static uint8_t uuid[16] = ACPI_PCI_UUID; + uint32_t buf[3]; + memset(args, 0, sizeof(args)); args[0].type = AML_OBJTYPE_BUFFER; args[0].v_buffer = uuid; @@ -112,10 +278,8 @@ acpipci_attach(struct device *parent, st buf[1] = ACPI_PCI_PCIE_CONFIG | ACPI_PCI_MSI; buf[2] = ACPI_PCI_PCIE_HOTPLUG; - if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res)) { - printf(": _OSC failed\n"); + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res)) return; - } if (res.type == AML_OBJTYPE_BUFFER) { size_t len = res.length; @@ -128,6 +292,4 @@ acpipci_attach(struct device *parent, st len -= 4; } } - - printf("\n"); } Index: dev/acpi/acpi.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.369 diff -u -p -r1.369 acpi.c --- dev/acpi/acpi.c 8 Jun 2019 12:25:19 -0000 1.369 +++ dev/acpi/acpi.c 9 Jun 2019 20:30:20 -0000 @@ -71,6 +71,7 @@ int acpi_debug = 16; int acpi_poll_enabled; int acpi_hasprocfvs; +int acpi_haspci; #define ACPIEN_RETRIES 15 Index: dev/acpi/acpivar.h =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v retrieving revision 1.100 diff -u -p -r1.100 acpivar.h --- dev/acpi/acpivar.h 7 Jun 2019 15:40:41 -0000 1.100 +++ dev/acpi/acpivar.h 9 Jun 2019 20:30:20 -0000 @@ -43,6 +43,7 @@ extern int acpi_debug; #endif extern int acpi_hasprocfvs; +extern int acpi_haspci; struct klist; struct acpiec_softc; Index: kern/subr_extent.c =================================================================== RCS file: /cvs/src/sys/kern/subr_extent.c,v retrieving revision 1.60 diff -u -p -r1.60 subr_extent.c --- kern/subr_extent.c 14 Nov 2018 17:52:48 -0000 1.60 +++ kern/subr_extent.c 9 Jun 2019 20:30:20 -0000 @@ -964,6 +964,7 @@ extent_free(struct extent *ex, u_long st struct extent_region *rp, *nrp = NULL; u_long end = start + (size - 1); int exflags; + int error = 0; #ifdef DIAGNOSTIC /* Check arguments. */ @@ -1081,6 +1082,11 @@ extent_free(struct extent *ex, u_long st } } + if (flags & EX_CONFLICTOK) { + error = EINVAL; + goto done; + } + /* Region not found, or request otherwise invalid. */ #if defined(DIAGNOSTIC) || defined(DDB) extent_print(ex); @@ -1095,7 +1101,7 @@ extent_free(struct extent *ex, u_long st ex->ex_flags &= ~EXF_WANTED; wakeup(ex); } - return (0); + return (error); } static struct extent_region *