Message ID | 1478768430-13422-2-git-send-email-jui.nee.tan@intel.com (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Andy Shevchenko |
Headers | show |
On Thu, 2016-11-10 at 17:00 +0800, Tan Jui Nee wrote: > From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > > There is already one and at least one more user coming which > require an access to Primary to Sideband bridge (P2SB) in order > to get IO or MMIO bar hidden by BIOS. > Create a driver to access P2SB for x86 devices. > > Signed-off-by: Yong, Jonathan <jonathan.yong@intel.com> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > +int p2sb_bar(struct pci_dev *pdev, unsigned int devfn, > + struct resource *res) > +{ > + u32 base_addr; > + u64 base64_addr; > + unsigned long flags; > + > > + if (!res) > + return -EINVAL; I don't remember the details, one version was quite changed, so, I think these lines are not needed anymore. > + /* Get IO or MMIO BAR */ > + pci_bus_read_config_dword(pdev->bus, devfn, SBREG_BAR, > &base_addr); > + if ((base_addr & PCI_BASE_ADDRESS_SPACE) == > PCI_BASE_ADDRESS_SPACE_IO) { > + flags = IORESOURCE_IO; > + base64_addr = base_addr & PCI_BASE_ADDRESS_IO_MASK; > + } else { > + flags = IORESOURCE_MEM; > + base64_addr = base_addr & PCI_BASE_ADDRESS_MEM_MASK; > + if (base_addr & PCI_BASE_ADDRESS_MEM_TYPE_64) { > + flags |= IORESOURCE_MEM_64; > > + pci_bus_read_config_dword(pdev->bus, devfn, > + SBREG_BAR + 4, &base_addr); Fix indentation. > + base64_addr |= (u64)base_addr << 32; > + } > + } > + > + /* Hide the P2SB device */ > + pci_bus_write_config_byte(pdev->bus, devfn, SBREG_HIDE, > 0x01); > + > + spin_unlock(&p2sb_spinlock); > + > + /* User provides prefilled resources */ Not anymore as far I as I can see. You just return here the result. > + res->start = (resource_size_t)base64_addr; > + res->flags = flags;
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogbGludXgtZ3Bpby1vd25l ckB2Z2VyLmtlcm5lbC5vcmcgW21haWx0bzpsaW51eC1ncGlvLQ0KPiBvd25lckB2Z2VyLmtlcm5l bC5vcmddIE9uIEJlaGFsZiBPZiBBbmR5IFNoZXZjaGVua28NCj4gU2VudDogRnJpZGF5LCBOb3Zl bWJlciAxMSwgMjAxNiAxMjowNyBBTQ0KPiBUbzogVGFuLCBKdWkgTmVlIDxqdWkubmVlLnRhbkBp bnRlbC5jb20+OyBtaWthLndlc3RlcmJlcmdAbGludXguaW50ZWwuY29tOw0KPiBoZWlra2kua3Jv Z2VydXNAbGludXguaW50ZWwuY29tOyB0Z2x4QGxpbnV0cm9uaXguZGU7IGR2aGFydEBpbmZyYWRl YWQub3JnOw0KPiBtaW5nb0ByZWRoYXQuY29tOyBocGFAenl0b3IuY29tOyB4ODZAa2VybmVsLm9y ZzsgcHR5c2VyQHhlcy1pbmMuY29tOw0KPiBsZWUuam9uZXNAbGluYXJvLm9yZzsgbGludXMud2Fs bGVpakBsaW5hcm8ub3JnDQo+IENjOiBsaW51eC1ncGlvQHZnZXIua2VybmVsLm9yZzsgcGxhdGZv cm0tZHJpdmVyLXg4NkB2Z2VyLmtlcm5lbC5vcmc7DQo+IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5l bC5vcmc7IFlvbmcsIEpvbmF0aGFuIDxqb25hdGhhbi55b25nQGludGVsLmNvbT47DQo+IFl1LCBP bmcgSG9jayA8b25nLmhvY2sueXVAaW50ZWwuY29tPjsgTHVjaywgVG9ueSA8dG9ueS5sdWNrQGlu dGVsLmNvbT47DQo+IFdhbiBNb2hhbWFkLCBXYW4gQWhtYWQgWmFpbmllIDx3YW4uYWhtYWQuemFp bmllLndhbi5tb2hhbWFkQGludGVsLmNvbT47DQo+IFN1biwgWXVueWluZyA8eXVueWluZy5zdW5A aW50ZWwuY29tPg0KPiBTdWJqZWN0OiBSZTogW1BBVENIIHYxMCAxLzZdIGRyaXZlcnMvcGxhdGZv cm0veDg2L3Ayc2I6IE5ldyBQcmltYXJ5IHRvDQo+IFNpZGViYW5kIGJyaWRnZSBzdXBwb3J0IGRy aXZlciBmb3IgSW50ZWwgU09DJ3MNCj4gDQo+IE9uIFRodSwgMjAxNi0xMS0xMCBhdCAxNzowMCAr MDgwMCwgVGFuIEp1aSBOZWUgd3JvdGU6DQo+ID4gRnJvbTogQW5keSBTaGV2Y2hlbmtvIDxhbmRy aXkuc2hldmNoZW5rb0BsaW51eC5pbnRlbC5jb20+DQo+ID4NCj4gPiBUaGVyZSBpcyBhbHJlYWR5 IG9uZSBhbmQgYXQgbGVhc3Qgb25lIG1vcmUgdXNlciBjb21pbmcgd2hpY2ggcmVxdWlyZQ0KPiA+ IGFuIGFjY2VzcyB0byBQcmltYXJ5IHRvIFNpZGViYW5kIGJyaWRnZSAoUDJTQikgaW4gb3JkZXIg dG8gZ2V0IElPIG9yDQo+ID4gTU1JTyBiYXIgaGlkZGVuIGJ5IEJJT1MuDQo+ID4gQ3JlYXRlIGEg ZHJpdmVyIHRvIGFjY2VzcyBQMlNCIGZvciB4ODYgZGV2aWNlcy4NCj4gPg0KPiA+IFNpZ25lZC1v ZmYtYnk6IFlvbmcsIEpvbmF0aGFuIDxqb25hdGhhbi55b25nQGludGVsLmNvbT4NCj4gPiBTaWdu ZWQtb2ZmLWJ5OiBBbmR5IFNoZXZjaGVua28gPGFuZHJpeS5zaGV2Y2hlbmtvQGxpbnV4LmludGVs LmNvbT4NCj4gDQo+IA0KPiA+ICtpbnQgcDJzYl9iYXIoc3RydWN0IHBjaV9kZXYgKnBkZXYsIHVu c2lnbmVkIGludCBkZXZmbiwNCj4gPiArCXN0cnVjdCByZXNvdXJjZSAqcmVzKQ0KPiA+ICt7DQo+ ID4gKwl1MzIgYmFzZV9hZGRyOw0KPiA+ICsJdTY0IGJhc2U2NF9hZGRyOw0KPiA+ICsJdW5zaWdu ZWQgbG9uZyBmbGFnczsNCj4gPiArDQo+ID4NCj4gDQo+ID4gKwlpZiAoIXJlcykNCj4gPiArCQly ZXR1cm4gLUVJTlZBTDsNCj4gDQo+IEkgZG9uJ3QgcmVtZW1iZXIgdGhlIGRldGFpbHMsIG9uZSB2 ZXJzaW9uIHdhcyBxdWl0ZSBjaGFuZ2VkLCBzbywgSSB0aGluaw0KPiB0aGVzZSBsaW5lcyBhcmUg bm90IG5lZWRlZCBhbnltb3JlLg0KPiANCk5vdGVkLCB0aGVzZSBsaW5lcyB3aWxsIGJlIHJlbW92 ZWQgaW4gbmV4dCBwYXRjaCB2ZXJzaW9uICh2MTIpLg0KPiA+ICsJLyogR2V0IElPIG9yIE1NSU8g QkFSICovDQo+ID4gKwlwY2lfYnVzX3JlYWRfY29uZmlnX2R3b3JkKHBkZXYtPmJ1cywgZGV2Zm4s IFNCUkVHX0JBUiwNCj4gPiAmYmFzZV9hZGRyKTsNCj4gPiArCWlmICgoYmFzZV9hZGRyICYgUENJ X0JBU0VfQUREUkVTU19TUEFDRSkgPT0NCj4gPiBQQ0lfQkFTRV9BRERSRVNTX1NQQUNFX0lPKSB7 DQo+ID4gKwkJZmxhZ3MgPSBJT1JFU09VUkNFX0lPOw0KPiA+ICsJCWJhc2U2NF9hZGRyID0gYmFz ZV9hZGRyICYgUENJX0JBU0VfQUREUkVTU19JT19NQVNLOw0KPiA+ICsJfSBlbHNlIHsNCj4gPiAr CQlmbGFncyA9IElPUkVTT1VSQ0VfTUVNOw0KPiA+ICsJCWJhc2U2NF9hZGRyID0gYmFzZV9hZGRy ICYgUENJX0JBU0VfQUREUkVTU19NRU1fTUFTSzsNCj4gPiArCQlpZiAoYmFzZV9hZGRyICYgUENJ X0JBU0VfQUREUkVTU19NRU1fVFlQRV82NCkgew0KPiA+ICsJCQlmbGFncyB8PSBJT1JFU09VUkNF X01FTV82NDsNCj4gPg0KPiANCj4gPiArCQkJcGNpX2J1c19yZWFkX2NvbmZpZ19kd29yZChwZGV2 LT5idXMsIGRldmZuLA0KPiA+ICsJCQkJU0JSRUdfQkFSICsgNCwgJmJhc2VfYWRkcik7DQo+IA0K PiBGaXggaW5kZW50YXRpb24uDQo+IA0KVGhhbmtzIGZvciBwb2ludGluZyB0aGF0IG91dC4gSSB3 aWxsIGZpeCB0aGF0IGluIG5leHQgcGF0Y2ggdmVyc2lvbiAodjEyKS4gDQo+ID4gKwkJCWJhc2U2 NF9hZGRyIHw9ICh1NjQpYmFzZV9hZGRyIDw8IDMyOw0KPiA+ICsJCX0NCj4gPiArCX0NCj4gPiAr DQo+ID4gKwkvKiBIaWRlIHRoZSBQMlNCIGRldmljZSAqLw0KPiA+ICsJcGNpX2J1c193cml0ZV9j b25maWdfYnl0ZShwZGV2LT5idXMsIGRldmZuLCBTQlJFR19ISURFLA0KPiA+IDB4MDEpOw0KPiA+ ICsNCj4gPiArCXNwaW5fdW5sb2NrKCZwMnNiX3NwaW5sb2NrKTsNCj4gPiArDQo+IA0KPiA+ICsJ LyogVXNlciBwcm92aWRlcyBwcmVmaWxsZWQgcmVzb3VyY2VzICovDQo+IA0KPiBOb3QgYW55bW9y ZSBhcyBmYXIgSSBhcyBJIGNhbiBzZWUuIFlvdSBqdXN0IHJldHVybiBoZXJlIHRoZSByZXN1bHQu DQo+IA0KQ3VycmVudCB2ZXJzaW9uIGlzIHJldHVybmluZyBzdGF0dXMgb2YgcDJzYl9iYXIgZnVu Y3Rpb24sIGkuZS4sIDAgb24gc3VjY2VzcyBvciBhcHByb3ByaWF0ZSBlcnJubyB2YWx1ZSBvbiBl cnJvci4gUGVyaGFwcyB5b3UgY291bGQgc2hhcmUgdGhlIHJlYXNvbiBvZiByZXR1cm4gdGhlIHJl c3VsdCBpbnN0ZWFkIG9mIHN0YXR1cy4gDQo+ID4gKwlyZXMtPnN0YXJ0ID0gKHJlc291cmNlX3Np emVfdCliYXNlNjRfYWRkcjsNCj4gPiArCXJlcy0+ZmxhZ3MgPSBmbGFnczsNCj4gDQo+IC0tDQo+ IEFuZHkgU2hldmNoZW5rbyA8YW5kcml5LnNoZXZjaGVua29AbGludXguaW50ZWwuY29tPg0KPiBJ bnRlbCBGaW5sYW5kIE95DQo+IC0tDQo+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBz ZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC1ncGlvIiBpbg0KPiB0aGUgYm9keSBvZiBh IG1lc3NhZ2UgdG8gbWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZyBNb3JlIG1ham9yZG9tbyBpbmZv IGF0DQo+IGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbA0K -- To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/x86/include/asm/p2sb.h b/arch/x86/include/asm/p2sb.h new file mode 100644 index 0000000..686e07b --- /dev/null +++ b/arch/x86/include/asm/p2sb.h @@ -0,0 +1,27 @@ +/* + * Primary to Sideband bridge (P2SB) access support + */ + +#ifndef P2SB_SYMS_H +#define P2SB_SYMS_H + +#include <linux/ioport.h> +#include <linux/pci.h> + +#if IS_ENABLED(CONFIG_P2SB) + +int p2sb_bar(struct pci_dev *pdev, unsigned int devfn, + struct resource *res); + +#else /* CONFIG_P2SB is not set */ + +static inline +int p2sb_bar(struct pci_dev *pdev, unsigned int devfn, + struct resource *res) +{ + return -ENODEV; +} + +#endif /* CONFIG_P2SB */ + +#endif /* P2SB_SYMS_H */ diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index b8a21d7..65ef6a0 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1027,4 +1027,8 @@ config INTEL_TELEMETRY used to get various SoC events and parameters directly via debugfs files. Various tools may use this interface for SoC state monitoring. + +config P2SB + tristate + depends on PCI endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 2efa86d..c39a13d 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -71,3 +71,4 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \ intel_telemetry_pltdrv.o \ intel_telemetry_debugfs.o obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o +obj-$(CONFIG_P2SB) += p2sb.o diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c new file mode 100644 index 0000000..b1d784c --- /dev/null +++ b/drivers/platform/x86/p2sb.c @@ -0,0 +1,98 @@ +/* + * Primary to Sideband bridge (P2SB) driver + * + * Copyright (c) 2016, Intel Corporation. + * + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Jonathan Yong <jonathan.yong@intel.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <linux/ioport.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/spinlock.h> + +#include <asm/p2sb.h> + +#define SBREG_BAR 0x10 +#define SBREG_HIDE 0xe1 + +static DEFINE_SPINLOCK(p2sb_spinlock); + +/* + * p2sb_bar - Get Primary to Sideband bridge (P2SB) BAR + * @pdev: PCI device to get PCI bus to communicate with + * @devfn: PCI device and function to communicate with + * @res: resources to be filled in + * + * The BIOS prevents the P2SB device from being enumerated by the PCI + * subsystem, so we need to unhide and hide it back to lookup the P2SB BAR. + * + * Locking is handled by spinlock - cannot sleep. + * + * Return: + * 0 on success or appropriate errno value on error. + */ +int p2sb_bar(struct pci_dev *pdev, unsigned int devfn, + struct resource *res) +{ + u32 base_addr; + u64 base64_addr; + unsigned long flags; + + if (!res) + return -EINVAL; + + spin_lock(&p2sb_spinlock); + + /* Unhide the P2SB device */ + pci_bus_write_config_byte(pdev->bus, devfn, SBREG_HIDE, 0x00); + + /* Check if device present */ + pci_bus_read_config_dword(pdev->bus, devfn, 0, &base_addr); + if (base_addr == 0xffffffff || base_addr == 0x00000000) { + spin_unlock(&p2sb_spinlock); + dev_warn(&pdev->dev, "P2SB device access disabled by BIOS?\n"); + return -ENODEV; + } + + /* Get IO or MMIO BAR */ + pci_bus_read_config_dword(pdev->bus, devfn, SBREG_BAR, &base_addr); + if ((base_addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { + flags = IORESOURCE_IO; + base64_addr = base_addr & PCI_BASE_ADDRESS_IO_MASK; + } else { + flags = IORESOURCE_MEM; + base64_addr = base_addr & PCI_BASE_ADDRESS_MEM_MASK; + if (base_addr & PCI_BASE_ADDRESS_MEM_TYPE_64) { + flags |= IORESOURCE_MEM_64; + pci_bus_read_config_dword(pdev->bus, devfn, + SBREG_BAR + 4, &base_addr); + base64_addr |= (u64)base_addr << 32; + } + } + + /* Hide the P2SB device */ + pci_bus_write_config_byte(pdev->bus, devfn, SBREG_HIDE, 0x01); + + spin_unlock(&p2sb_spinlock); + + /* User provides prefilled resources */ + res->start = (resource_size_t)base64_addr; + res->flags = flags; + + return 0; +} +EXPORT_SYMBOL_GPL(p2sb_bar); + +MODULE_LICENSE("GPL v2");