Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp4207733pxv; Mon, 19 Jul 2021 20:30:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwn1B/laITHFXwblHNfQlU4zNCWZsrOIDEYRpI4AoBVmkVr4yfoLkmkkbDtFwJQoaLZdkkC X-Received: by 2002:a17:906:7691:: with SMTP id o17mr31459418ejm.209.1626751800315; Mon, 19 Jul 2021 20:30:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626751800; cv=none; d=google.com; s=arc-20160816; b=jqrdWaxz2lRb3SL+4Iu8LgNmUvjuo9w68478ARcJ5WkDx2JwbJuBevOWRg68o2VNjV OADkOkgngliQR3xubBo71CbXDGGR36uR6fg7vgbzV83/A+0jjbgz4h9sY74ZD62wfOvW Ok8iTRnJRGKJh7kf3ixknwchU/JnqI7cExKF5cl+BaDt119CknB96k0HW0BS1C/LFWwe jdNX+pjg5g+ThbZZYqjIfZq0DTEmjf/Kf82INOjpmdAXtckOX05Q3+m6SwWL3lZhtEpv KelPBmqhsJ75L06VbxXVU9LgkL6z9516/+kcr1xagnltjvxa6lgryriYHgTzxwqp53DQ mOfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:message-id :in-reply-to:subject:cc:to:from:date; bh=WI0q4Wa9ulSjESkf4pR/QAhG2360q3kLArWS37agRCw=; b=cJng9vq3CPBDFPQmZRKfSDS4845kxg1uf6V69MqhxRvMO7gBjh4FeQy6nnB17nLvOt 8r6d5DAWw+etJP5JOywsmE7zZoquaJ3pmRqTytmk7RM2EXeQWwXzyUUsaTbNgepUBZn7 pU1GlP+ZtkD8AzvS6oTXPDAwRSQfANuw3ZVdmFNM1z1GdSPSGRgnBMmcOWMsOJA4MM8U Shhv28AUtcaTO6hRr0X/NG4JujcU3ML4gem66jcAz6+Wf4+TrsZ5kTb1Yfd9dHE+QPst Y0Zg3jrZb4jdO/KaZGAosB9w7wmmuFrEPL9EKj+L1B9N0EAGlovrKPNAwz8pxlHEbx3Y hJow== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u6si23653594eju.58.2021.07.19.20.29.37; Mon, 19 Jul 2021 20:30:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243409AbhGTCrk (ORCPT + 99 others); Mon, 19 Jul 2021 22:47:40 -0400 Received: from angie.orcam.me.uk ([78.133.224.34]:60864 "EHLO angie.orcam.me.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242706AbhGTCrW (ORCPT ); Mon, 19 Jul 2021 22:47:22 -0400 Received: by angie.orcam.me.uk (Postfix, from userid 500) id C65E19200B4; Tue, 20 Jul 2021 05:27:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id BF5179200B3; Tue, 20 Jul 2021 05:27:59 +0200 (CEST) Date: Tue, 20 Jul 2021 05:27:59 +0200 (CEST) From: "Maciej W. Rozycki" To: Nikolai Zhubr , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Bjorn Helgaas , "Rafael J. Wysocki" , Len Brown , Pavel Machek , Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel cc: x86@kernel.org, linux-pci@vger.kernel.org, linux-pm@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/6] x86/PCI: Add support for the Intel 82374EB/82374SB (ESC) PIRQ router In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The Intel 82374EB/82374SB EISA System Component (ESC) devices implement PCI interrupt steering with a PIRQ router[1] in the form of four PIRQ Route Control registers, available in the port I/O space accessible indirectly via the index/data register pair at 0x22/0x23, located at indices 0x60/0x61/0x62/0x63 for the PIRQ0/1/2/3# lines respectively. The semantics is the same as with the PIIX router, however it is not clear if BIOSes use register indices or line numbers as the cookie to identify PCI interrupts in their routing tables and therefore support either scheme. Accesses to the port I/O space concerned here need to be unlocked by writing the value of 0x0f to the ESC ID Register at index 0x02 beforehand[2]. Do so then and then lock access after use for safety. This locking could possibly interfere with accesses to the Intel MP spec IMCR register, implemented by the 82374SB variant of the ESC only as the PCI/APIC Control Register at index 0x70[3], for which leaving access to the configuration space concerned unlocked may have been a requirement for the BIOS to remain compliant with the MP spec. However we only poke at the IMCR register if the APIC mode is used, in which case the PIRQ router is not, so this arrangement is not going to interfere with IMCR access code. The ESC is implemented as a part of the combined southbridge also made of 82375EB/82375SB PCI-EISA Bridge (PCEB) and does itself appear in the PCI configuration space. Use the PCEB's device identification then for determining the presence of the ESC. References: [1] "82374EB/82374SB EISA System Component (ESC)", Intel Corporation, Order Number: 290476-004, March 1996, Section 3.1.12 "PIRQ[0:3]#--PIRQ Route Control Registers", pp. 44-45 [2] same, Section 3.1.1 "ESCID--ESC ID Register", p. 36 [3] same, Section 3.1.17 "PAC--PCI/APIC Control Register", p. 47 Signed-off-by: Maciej W. Rozycki --- arch/x86/pci/irq.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) linux-x86-pirq-router-esc.diff Index: linux-macro-pirq/arch/x86/pci/irq.c =================================================================== --- linux-macro-pirq.orig/arch/x86/pci/irq.c +++ linux-macro-pirq/arch/x86/pci/irq.c @@ -359,6 +359,74 @@ static int pirq_ali_set(struct pci_dev * } /* + * PIRQ routing for the 82374EB/82374SB EISA System Component (ESC) + * ASIC used with the Intel 82420 and 82430 PCIsets. The ESC is not + * decoded in the PCI configuration space, so we identify it by the + * accompanying 82375EB/82375SB PCI-EISA Bridge (PCEB) ASIC. + * + * There are four PIRQ Route Control registers, available in the + * port I/O space accessible indirectly via the index/data register + * pair at 0x22/0x23, located at indices 0x60/0x61/0x62/0x63 for the + * PIRQ0/1/2/3# lines respectively. The semantics is the same as + * with the PIIX router. + * + * Accesses to the port I/O space concerned here need to be unlocked + * by writing the value of 0x0f to the ESC ID Register at index 0x02 + * beforehand. Any other value written to said register prevents + * further accesses from reaching the register file, except for the + * ESC ID Register being written with 0x0f again. + * + * References: + * + * "82374EB/82374SB EISA System Component (ESC)", Intel Corporation, + * Order Number: 290476-004, March 1996 + * + * "82375EB/82375SB PCI-EISA Bridge (PCEB)", Intel Corporation, Order + * Number: 290477-004, March 1996 + */ + +#define PC_CONF_I82374_ESC_ID 0x02u +#define PC_CONF_I82374_PIRQ_ROUTE_CONTROL 0x60u + +#define PC_CONF_I82374_ESC_ID_KEY 0x0fu + +static int pirq_esc_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + unsigned long flags; + int reg; + u8 x; + + reg = pirq; + if (reg >= 1 && reg <= 4) + reg += PC_CONF_I82374_PIRQ_ROUTE_CONTROL - 1; + + raw_spin_lock_irqsave(&pc_conf_lock, flags); + pc_conf_set(PC_CONF_I82374_ESC_ID, PC_CONF_I82374_ESC_ID_KEY); + x = pc_conf_get(reg); + pc_conf_set(PC_CONF_I82374_ESC_ID, 0); + raw_spin_unlock_irqrestore(&pc_conf_lock, flags); + return (x < 16) ? x : 0; +} + +static int pirq_esc_set(struct pci_dev *router, struct pci_dev *dev, int pirq, + int irq) +{ + unsigned long flags; + int reg; + + reg = pirq; + if (reg >= 1 && reg <= 4) + reg += PC_CONF_I82374_PIRQ_ROUTE_CONTROL - 1; + + raw_spin_lock_irqsave(&pc_conf_lock, flags); + pc_conf_set(PC_CONF_I82374_ESC_ID, PC_CONF_I82374_ESC_ID_KEY); + pc_conf_set(reg, irq); + pc_conf_set(PC_CONF_I82374_ESC_ID, 0); + raw_spin_unlock_irqrestore(&pc_conf_lock, flags); + return 1; +} + +/* * The Intel PIIX4 pirq rules are fairly simple: "pirq" is * just a pointer to the config space. */ @@ -768,6 +836,11 @@ static __init int intel_router_probe(str switch (device) { u8 rid; + case PCI_DEVICE_ID_INTEL_82375: + r->name = "PCEB/ESC"; + r->get = pirq_esc_get; + r->set = pirq_esc_set; + return 1; case PCI_DEVICE_ID_INTEL_82378: pci_read_config_byte(router, PCI_REVISION_ID, &rid); /* Tell 82378IB (rev < 3) and 82378ZB/82379AB apart. */