static void quirk_intel_mch()

in quirks.c [362:413]


static void quirk_intel_mch(struct pnp_dev *dev)
{
	struct pci_dev *host;
	u32 addr_lo, addr_hi;
	struct pci_bus_region region;
	struct resource mch;
	struct pnp_resource *pnp_res;
	struct resource *res;

	host = get_intel_host();
	if (!host)
		return;

	/*
	 * MCHBAR is not an architected PCI BAR, so MCH space is usually
	 * reported as a PNP0C02 resource.  The MCH space was originally
	 * 16KB, but is 32KB in newer parts.  Some BIOSes still report a
	 * PNP0C02 resource that is only 16KB, which means the rest of the
	 * MCH space is consumed but unreported.
	 */

	/*
	 * Read MCHBAR for Host Member Mapped Register Range Base
	 * https://www-ssl.intel.com/content/www/us/en/processors/core/4th-gen-core-family-desktop-vol-2-datasheet
	 * Sec 3.1.12.
	 */
	pci_read_config_dword(host, 0x48, &addr_lo);
	region.start = addr_lo & ~0x7fff;
	pci_read_config_dword(host, 0x4c, &addr_hi);
	region.start |= (u64) addr_hi << 32;
	region.end = region.start + 32*1024 - 1;

	memset(&mch, 0, sizeof(mch));
	mch.flags = IORESOURCE_MEM;
	pcibios_bus_to_resource(host->bus, &mch, &region);

	list_for_each_entry(pnp_res, &dev->resources, list) {
		res = &pnp_res->res;
		if (res->end < mch.start || res->start > mch.end)
			continue;	/* no overlap */
		if (res->start == mch.start && res->end == mch.end)
			continue;	/* exact match */

		dev_info(&dev->dev, FW_BUG "PNP resource %pR covers only part of %s Intel MCH; extending to %pR\n",
			 res, pci_name(host), &mch);
		res->start = mch.start;
		res->end = mch.end;
		break;
	}

	pci_dev_put(host);
}